コンパイラがasyncキーワードを使用してコンパイルするときにTaskSchedulerを選択する方法の背後にある理由を知りたいです。
私のテストメソッドは、OnConnectedAsyncメソッドのSignalR(ASP.NETホスト、IIS8、WebSocketトランスポート)によって呼び出されます。
protected override async Task OnConnectedAsync(IRequest request, string connectionId)
{
SendUpdates();
}
現在の同期コンテキストでタスクを開始すると、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");
}
});
}
しかし、さらに興味深いのは、例外が発生しない場合です。次の作品:
private void SendUpdates()
そして、以下も動作します
private async Task SendUpdates()
この最後のものも機能しますが、基本的には上記の例と同じです。
private Task SendUpdates()
{
return Task.Run(async () =>
{
while (true)
{
await Task.Delay(1000);
await Connection.Broadcast("blabla");
}
});
}
コンパイラがここで使用するスケジューラをどのように選択するか知っていますか?