【发布时间】:2017-07-20 11:29:00
【问题描述】:
我正在尝试开发概念验证应用程序,我想了解以下两个异步方法的内部结构。
Task.Result 会导致DoSomethingAsync1() 出现任何问题吗?
我已经阅读了一些关于Task.Result 可能导致的阻塞和死锁问题,但我认为在这种情况下不会,因为它在单独的任务上运行并且任务上有一个await这已经确保了结果。
这里的主要目标是在一个单独的任务上运行异步方法,因为这个操作不依赖于主 asp.net 线程,更重要的是捕获DoSomethingThatTakesReallyLong()抛出的任何异常
另外,在ActionResultDoSomething(),我应该设置.ConfigureAwait(false);吗?
在以下场景中我需要注意任何隐藏的瓶颈/问题吗?
更新
我已经修正了在这里输入问题时的错字。 (返回用户对象而不是任务)
另外,我不能在实际应用程序中一次将所有高级方法转换为async。所以,这是我计划一步一步做的事情,从不依赖于主线程的操作开始。
我也非常感谢所有最佳实践的答案,但这是一个小操场代码,我的主要问题是知道 DoSomethingAsync1() 和 DoSomethingAsync2() 之间是否存在内部差异,这可能会导致某些问题健康)状况。
通过阅读 cmets 和答案,我知道没有太大区别。
private static async Task<User> DoSomethingAsync1()
{
try
{
var longRunningTask = Task<User>.Factory.StartNew(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong());
var user = await longRunningTask;
//Will the below line of code cause any issue?
Console.WriteLine(longRunningTask.Result.Id);
return user;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
private static async Task<User> DoSomethingAsync2()
{
try
{
var longRunningTask = Task<User>.Factory.StartNew(() => LongRunner.LongRunnerInstance.DoSomethingThatTakesReallyLong());
var user = await longRunningTask;
Console.WriteLine(user.Id);
return user;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return null;
}
}
public ActionResult Index()
{
//Things that run on main Asp.NET thread
//Things that run independently
//Won't be using the task returned here at the moment.
DoSomethingAsync1();
//Do more things on main Asp.NET thread if needed
return View();
}
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
谢谢
【问题讨论】:
-
我不希望您的第一个代码能够编译,因为您正试图从返回类型为
Task<User>的 async 方法返回Task<User>。该方法中的 return 语句应尝试返回User。 -
另外,
Task<T>.Factory.StartNew()是一个遗留函数,不应该与 async 关键字一起使用 -
我在这里输入的时候一定是打错了。会更新的
-
你为什么要删除@MikeT 的答案,我赞成!感谢您提供的一些澄清!
-
@Ren 因为我简化了一些细节而不是让你埋头于后端如何工作的细节中,所以它被拖了后腿,这不值得恶化
标签: c# .net multithreading async-await