gpt4 book ai didi

c# - async 关键字和 TaskScheduler 的选择

转载 作者:太空狗 更新时间:2023-10-29 18:16:31 24 4
gpt4 key购买 nike

我想知道编译器在使用 async 关键字进行编译时选择 TaskScheduler 的方式背后的原因。

我的测试方法由 SignalR(ASP.NET 主机、IIS8、websocket 传输)在 OnConnectedAsync 方法上调用。

protected override async Task OnConnectedAsync(IRequest request, string connectionId)
{
SendUpdates();
}

在当前同步上下文中启动任务将导致 System.Web.AspNetSynchronizationContext.OperationStarted() 中出现 InvalidOperationException

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>.

很好。使用此 SendUpdates 定义,我得到了上述异常:

    private async void SendUpdates()
{
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
await Connection.Broadcast("blabla");
}
});

}

但更有趣的是当我没有得到异常时。以下作品:

    private void SendUpdates()

下面的也行

    private async Task SendUpdates()

最后一个也可以,但它与上面的例子本质上是一样的。

    private Task SendUpdates()
{
return Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
await Connection.Broadcast("blabla");
}
});

}

你知道编译器是如何选择在这里使用哪个调度器的吗?

最佳答案

编写 async 代码的主要准则之一是“避免 async void”——也就是说,使用 async Task 而不是 async void 除非您正在实现 async 事件处理程序。

async void 方法使用SynchronizationContextOperationStartedOperationCompleted;请参阅我的 MSDN 文章 It's All about the SynchronizationContext了解更多详情。

ASP.NET 检测到对 OperationStarted 的调用并(正确地)拒绝它,因为在那里放置 async 事件处理程序是非法的。当您更正代码以使用 async Task 时,ASP.NET 将不再看到 async 事件处理程序。

你可以找到我的 intro to async / await post有帮助。

关于c# - async 关键字和 TaskScheduler 的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13031144/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com