Eil*_*aee 8 c# async-await signalr
我想知道编译器在使用async关键字进行编译时选择TaskScheduler的方式背后的原因.
我的测试方法由OnConnectedAsync方法上的SignalR(ASP.NET主机,IIS8,websocket传输)调用.
protected override async Task OnConnectedAsync(IRequest request, string connectionId)
{
SendUpdates();
}
Run Code Online (Sandbox Code Playgroud)
在Current同步上下文中启动任务将导致System.Web.AspNetSynchronizationContext.OperationStarted()中的InvalidOperationException
此时无法启动异步操作.异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动.如果在执行页面时发生此异常,请确保标记页面
<%@ Page Async="true" %>.
精细.使用此SendUpdates定义,我得到以上异常:
private async void SendUpdates()
{
Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
await Connection.Broadcast("blabla");
}
});
}
Run Code Online (Sandbox Code Playgroud)
但更有趣的是,当我没有得到例外.以下作品:
private void SendUpdates()
Run Code Online (Sandbox Code Playgroud)
以下也有效
private async Task SendUpdates()
Run Code Online (Sandbox Code Playgroud)
这最后一个也有效,但它与上面的例子基本相同.
private Task SendUpdates()
{
return Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
await Connection.Broadcast("blabla");
}
});
}
Run Code Online (Sandbox Code Playgroud)
你知道编译器如何选择在这里使用哪个调度程序吗?
Ste*_*ary 12
编写async代码的主要原则之一是"避免async void" - 也就是说,除非您正在实现事件处理程序async Task,async void否则请使用async.
async void方法使用SynchronizationContext的OperationStarted和OperationCompleted; 有关详细信息,请参阅我的MSDN文章所有关于SynchronizationContext的内容.
ASP.NET检测到调用OperationStarted和(正确)拒绝它,因为在async那里放置事件处理程序是非法的.当您更正要使用的代码时async Task,ASP.NET不再看到async事件处理程序.
您可能会发现我的介绍async/ await发布有用.