【发布时间】:2015-12-08 21:07:49
【问题描述】:
根据this link:
当您使用 await 关键字等待方法时,编译器会代表您生成一堆代码。这样做的目的之一 action 是处理与 UI 线程的同步。关键
此功能的组件是SynchronizationContext.Current它获取当前线程的同步上下文。SynchronizationContext.Current的填充取决于
您所在的环境。Task 的GetAwaiter方法查找SynchronizationContext.Current。如果当前同步上下文 不为空,传递给该等待者的延续将 回发到该同步上下文。当以阻塞方式使用使用新异步语言特性的方法时,如果
您有可用的SynchronizationContext。 当您在 以阻塞方式使用此类方法(等待任务 使用 Wait 方法或直接从 Result 中获取结果 任务的属性),您将同时阻塞主线程 时间。当最终任务在该方法内完成时 线程池,它将调用延续回发到 主线程因为SynchronizationContext.Current是 可用和捕获。但是这里有个问题:UI线程 被阻止了,你有一个死锁!
public class HomeController : Controller
{
public ViewResult CarsSync()
{
SampleAPIClient client = new SampleAPIClient();
var cars = client.GetCarsInAWrongWayAsync().Result;
return View("Index", model: cars);
}
}
public class SampleAPIClient
{
private const string ApiUri = "http://localhost:17257/api/cars";
public async Task<IEnumerable<Car>> GetCarsInAWrongWayAsync()
{
using (var client = new HttpClient())
{
var response = await client.GetAsync(ApiUri);
// Not the best way to handle it but will do the work for demo purposes
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsAsync<IEnumerable<Car>>();
}
}
}
我无法理解上面语句的 粗体 部分,但是当我测试上面的代码时,它会按预期死锁。 但是我还是不明白为什么UI线程被阻塞了?
在这种情况下,可用的SynchronizationContext 是什么?是 UI 线程吗?
【问题讨论】:
-
这是来自here 吗?如果是这样,您最好在问题中包含指向它的链接,并指出其中大部分是引用。
-
这不是您问题的直接答案,但是如果您将控制器操作结果设为
Task<ViewResult>,它可以一直异步(就 ASP.NET 线程使用而言,它可以更好地扩展) -
@Damien_The_Unbeliever 是的,我添加了链接。谢谢
-
将引用文本设为“引用”,因此很明显您引用了该网站
-
@Groo 我很抱歉。我的英语不好。谢谢你的帮助。
标签: c# .net asynchronous