2014-10-16 44 views
2

我有一个简单的单元测试:'收藏已修改;枚举操作可能不会执行”使用异步/等待

[TestMethod] 
public void TestInitDatabases() 
{ 
    Debug.WriteLine("Testing loading up all databases!"); 

    Assert.IsTrue(Library.InitDatabase()); 
} 

而且在试图加载实体58139个记录ClassLibrary一个方法。

public static bool InitDatabase() 
{ 
    Debug.WriteLine("Loading Entities"); 

    var startTime = DateTime.Now; 

    DContext.Database.CommandTimeout = 180; 
    DContext.Database.Log = Console.WriteLine; 

    Task task = new Task(async() => await DContext.SA_HistoryHeader.LoadAsync()); 

    Debug.WriteLine("All Tasks Assigned"); 

    task.Start(); 
    task.Wait(); 
    while (!DContext.SA_HistoryHeader.Local.Any()) 
    { 
     Debug.WriteLine("Task Status " + task.Status); 
    } 

    try 
    { 
     Debug.WriteLine("We are about to count the records..."); 

     while (DContext.SA_HistoryHeader.Local.Count != 58139) 
     { 
      Debug.WriteLine("OrderHistory has " + DContext.SA_HistoryHeader.Local.Count + " Records"); 
     } 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine("Count Error: " + ex.Message); 
     return false; 
    } 

    Debug.WriteLine("Total Load Time: " + (DateTime.Now – startTime)); 

    return true; 
} 

但try/catch语句返回:

Count Error: Collection was modified; enumeration operation may not execute.

我每次运行测试。

输出显示:

... 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
A first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll 
Count Error: Collection was modified; enumeration operation may not execute. 
A first chance exception of type 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException' occurred in Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll 
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll 
A first chance exception of type 'Microsoft.VisualStudio.TestTools.TestTypes.Unit.TestFailedException' occurred in Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter.dll 
The thread 'Agent: adapter run thread for test 'TestInitDatabases' with id '97fef094-3e43-4bfa-bb1d-02b70eb4b6f7'' (0x19ac) has exited with code 0 (0x0). 
The thread 'Agent: test queue thread' (0x3a0) has exited with code 0 (0x0). 
The thread 'Agent: state execution thread for test 'TestInitDatabases' with id '97fef094-3e43-4bfa-bb1d-02b70eb4b6f7'' (0x138c) has exited with code 0 (0x0). 
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll 
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll 
A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll 
... 

偶尔,我会得到:

... 
OrderHistory has 1 Records 
OrderHistory has 1 Records 
OrderHistory has 513 Records 

然后同样的错误。我正在尝试查找加载实体表的最快方法。

编辑:我根据尤瓦Itzchakov的评论改变了我的方法:

public static async void InitDatabase() 
    { 
     Debug.WriteLine("Loading Entities"); 

     var startTime = DateTime.Now; 
     DateTime newTime; 


     DContext.Database.CommandTimeout = 180; 
     DContext.Database.Log = Console.WriteLine; 

     try 
     { 
      await DContext.SA_HistoryHeader.LoadAsync(); 
      //DContext.SA_HistoryHeader.Load(); 
      Debug.WriteLine("Orders has " + DContext.SA_HistoryHeader.Local.Count + " records"); 
      Debug.WriteLine("OrderHistory Loaded: " + (DateTime.Now - startTime)); 
      newTime = DateTime.Now; 
      await DContext.SA_HistoryDetail.LoadAsync(); 
      //DContext.SA_HistoryDetail.Load(); 
      Debug.WriteLine("Details has " + DContext.SA_HistoryDetail.Local.Count + " records"); 
      Debug.WriteLine("OrderDetails Loaded: " + (DateTime.Now - newTime)); 
     } 
     catch (SqlException ex) 
     { 
      foreach (SqlError error in ex.Errors) 
      Debug.WriteLine("Sql Exception Error: " + error.Message); 
      return; 
     } 
     catch (ThreadAbortException ex) 
     { 
      Debug.WriteLine("Thread - caught ThreadAbortException - resetting."); 
      Debug.WriteLine(string.Format("Exception message: {0}", ex.Message)); 
      Thread.ResetAbort(); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine("Load Exception Error: " + ex.Message); 
      return; 
     } 

     Debug.WriteLine("All Tasks Complete: " + (DateTime.Now - startTime)); 

     return; 
    } 

当我使用普通的老负荷订单实体处于〜47秒加载。细节实体需要大约19分钟才能加载(358,501条记录)。

当我更改(注释/取消注释)到LoadAsync时,我所得到的全部是线程中止异常。

+0

你是否真的想等到'LoadAsync'完成?因为这不是目前正在发生的事情。 – 2014-10-16 17:34:31

+0

@YuvalItzchakov,是的,我想等待LoadAsync完成。 – Randy 2014-10-16 17:38:37

+0

只是'等待LoadAsync'。不需要你所有的任务,你会过分复杂并引入错误。 – 2014-10-16 17:42:28

回答

5

目前发生的情况是,您实际上正在等待由new Task创建的外部任务,这意味着当您使用Task.Wait时,它将立即返回并且不会等待内部任务完成。

我不明白了一个道理,以创建一个new Task当你做操作IO的约束,你可以简单地await操作:

await DContext.SA_HistoryHeader.LoadAsync() 

这将保证在操作完成之前收集数据你看看Count属性。

相关问题