ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#-Web API同步调用最佳实践

2019-11-20 05:05:05  阅读:215  来源: 互联网

标签:asp-net-web-api iis net-4-5 c


可能已经提出了这个问题,但我从未找到明确的答案.假设我在IIS上托管了一个Web API 2.0应用程序.我想我了解最佳实践(防止客户端上的死锁)始终使用从GUI事件到HttpClient调用的异步方法.这很好,并且有效.但是,如果我的客户端应用程序没有GUI(例如Window Service,Console Application),而只有同步方法可以进行调用,那么最佳实践是什么?在这种情况下,我使用以下逻辑:

void MySyncMethodOnMyWindowServiceApp()
{
  list = GetDataAsync().Result().ToObject<List<MyClass>>();
} 

async Task<Jarray> GetDataAsync()
{
  list = await Client.GetAsync(<...>).ConfigureAwait(false);
  return await response.Content.ReadAsAsync<JArray>().ConfigureAwait(false);
}

但是不幸的是,这仍然可能导致客户机上的死锁,这在随机机器上随机发生.

客户端应用程序此时停止,再也不会返回:

list = await Client.GetAsync(<...>).ConfigureAwait(false);

解决方法:

如果它可以在后台运行并且不被强制同步,请尝试将代码(调用async方法)包装在Task.Run()中.我不确定这是否会解决“死锁”问题(如果这不同步,那就是另一个问题),但是如果您想从异步/等待中受益,如果您一直没有异步,我不确定是否有好处,除非您在后台线程中运行它.我有一种情况是在几个地方添加Task.Run()(在我的情况下,是从我更改为异步的MVC控制器添加)并调用异步方法不仅稍微提高了性能,而且提高了可靠性(不确定是一个“僵局”,但在重负载下看起来类似).

您会发现使用Task.Run()在某些情况下被认为是一种不好的方法,但是在我的情况下,我真的看不到更好的方法,而且确实确实是一种改进.也许这是其中一种理想的方法,而不是让它在您不完美的情况下工作的方法之一.:-)

[根据要求提供的代码进行了更新]

因此,正如其他人发布的那样,您应该“一直向下同步”.就我而言,我的数据不是异步的,但我的UI是.因此,我尽可能地降低了异步速度,然后以合理的方式用Task.Run封装了数据调用.我认为,这是弄清楚事情可以并行运行是否有意义的诀窍,否则,您就是同步的(如果您使用异步并立即解决它,则迫使它等待答案).我有许多可以并行执行的读取.

在上面的示例中,我认为您必须尽可能合理地进行异步,然后在某个时候确定您可以在哪里进行分拆并独立于其他代码执行操作.假设您有一个保存数据的操作,但是您实际上不需要等待响应-您保存它就完成了.您唯一需要注意的就是不要在不等待该线程/任务完成的情况下关闭程序.在您的代码中有意义的地方取决于您.

语法很简单.我采用了现有代码,将控制器更改为异步函数,以返回以前返回的类的Task.

var myTask = Task.Run(() =>
{
   //...some code that can run independently....  In my case, loading data
});
// ...other code that can run at the same time as the above....

await Task.WhenAll(myTask, otherTask); 
//..or...
await myTask;

//At this point, the result is available from the task
myDataValue = myTask.Result;

请参阅MSDN以获得更好的示例:
 https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx

[更新2,与原始问题更相关]

假设您读取的数据是异步方法.

private async Task<MyClass> Read()

您可以调用它,保存任务,并在准备就绪时等待它:

var runTask = Read();
//... do other code that can run in parallel

await runTask;

因此,为此目的,调用异步代码,这是原始发布者所要求的,我认为您不需要Task.Run(),尽管除非您是异步的,否则我不认为您可以使用“ await”方法-您将需要Wait的备用语法.

诀窍在于,无需并行运行一些代码,其中没有什么意义,因此考虑多线程仍然是重点.

标签:asp-net-web-api,iis,net-4-5,c
来源: https://codeday.me/bug/20191120/2041740.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有