2015-11-09 113 views
1

我已经调整了以下代码,尝试从Wasson的asp.net代码的web api加载。如何测试以确保此代码真正运行异步?

static public async Task<IEnumerable<T>> ExecuteAsync(HttpClient client, String endPoint) 
    { 
     IEnumerable<T> result = null; 
     HttpResponseMessage response = client.GetAsync(endPoint).Result; 
     response.EnsureSuccessStatusCode(); 
     if (response.IsSuccessStatusCode) 
     { 
      var tResult = await response.Content.ReadAsStringAsync(); 
      result = JsonConvert.DeserializeObject<IEnumerable<T>>(tResult); 
     } 
     return result; 
    } 

当我有它的设计,我觉得这个过程将异步运行,但我不知道如何测试它,以确保它。

我是使用异步编码的新手,所以任何建议都会有所帮助。

调用过程如下:

public virtual IEnumerable<T> Fill() 
    { 
     IEnumerable<T> result = null; 
     try 
     { 
      using (var client = CreateClient("", new MediaTypeWithQualityHeaderValue("application/json"))) 
      { 

       String _endPoint = "api/" + typeof(T).Name + "/Get"; 

       result = (ExecuteAsync(client, _endPoint)).Result; 
      } 
     } 
     catch (Exception ex) 
     { 
      LogError(ex.Message); 

     } 
     return result; 
    } 

是这个组合可能因为我希望它异步运行?

我希望能够异步运行的原因是,填充程序获取大量的数据库中的数据的。对于每条记录来说,更多的情况是大量的单个记录而不是大的记录,尽管一些记录的大小也可能是一个问题。

我不想坐在那里等待整个页面与数据库通信正在发生加载用户。

这并不重要,在这种情况下,我是否直接连接到数据库或通过我使用的网络API会:这需要在某些情况下,无论哪种方式,很长一段时间。

我也很关心死锁:一个大的取进来,而另一个正在等待。

我最初构图之后麦克沃森的示例代码的代码,却发现代码,即使它编译无限期忌用。

这是否有助于改善情况?

+0

编号'.Result'使其成为阻塞呼叫。 'Fill'应该标记为'async',以便您可以调用'result = await ExecuteAsync(client,_endpoint);' –

+0

在Visual Studio中,我相信您的输出会告诉您何时使用的线程正在退出。这就是我一直看到的,如果异步实际上是创建线程。我的逻辑可能是错误的,但如果它没有在那里显示多个线程,那么我认为它没有......并且到目前为止它是正确的。 – trueCamelType

+0

至于测试一些建议。起初,我陷入陷阱使用'await Task.Delay(TimeInMillisecondsHere)',但后来意识到,你需要一个阻止操作来实际测试,所以现在使用for循环像'for(int i = 0; i kirotab

回答

0

不知道你在这里后交配。 您发布的代码仍然会阻止它所在的线程,因为您正在调用将阻止的结果。

result = (ExecuteAsync(client, _endPoint)).Result; 

您可以通过让异步和await关键字传播回最初创建请求的任何方法来使它异步。

public virtual async Task<IEnumerable<T>> Fill() 
{ 
    ... 
    result = await ExecuteAsync(client, _endPoint); 
    ... 
} 

但是我不知道这真的是你追求的,因为你提到

我不想坐在那里等待整个页面而加载用户与数据库的通信正在发生。

默认情况下,使事情异步你会不会解决这个问题。完成15秒的操作需要15秒才能完成,无论它是同步还是异步。不同之处在于,如果它是异步的,那么你的资源效率会更高(这意味着,您可以释放线程来完成其他任务,同时等待某些内容完成)。

但是,您可以使用任务来实现并行性。举个例子:

public void DoWork() 
{ 
    Thread.Sleep(10000); 
} 

public void DoMoreWork() 
{ 
    Thread.Sleep(10000); 
} 

如果我们叫这两个这样

DoWork(); 
DoMoreWork(); 

然后,将采取20000毫秒秒或20秒 如果我们让它异步

public async Task DoWork() 
{ 
    await Task.Delay(10000); 
} 

public async Task DoMoreWork() 
{ 
    await Task.Delay(10000); 
} 

和呼叫它是这样的

await DoWork(); 
await DoMoreWork(); 

然后它仍然需要20秒才能完成。然而,由于DoWork的和DoMoreWork可以从eachothers独立操作,我们可以在同一时间做

await Task.WhenAll(DoWork(), DoMoreWork()); 

这将(在一个完美的世界)导致这两个任务运行它们都在10秒内正在做减半时间用户必须等待。

希望我对这个问题有所了解:)