私はこの簡単なコードを持っています:
public static async Task<int> SumTwoOperationsAsync()
{
var firstTask = GetOperationOneAsync();
var secondTask = GetOperationTwoAsync();
return await firstTask + await secondTask;
}
private async Task<int> GetOperationOneAsync()
{
await Task.Delay(500); // Just to simulate an operation taking time
return 10;
}
private async Task<int> GetOperationTwoAsync()
{
await Task.Delay(100); // Just to simulate an operation taking time
return 5;
}
すばらしいです。これがコンパイルされます。
しかし、私はコンソールアプリを持っていて、上記のコードを実行したいとします(SumTwoOperationsAsync()
を呼び出します)
static void Main(string[] args)
{
SumTwoOperationsAsync();
}
しかし、私はそれを読んだ(sync
を使用するとき)私はすべての方法で同期する必要がありますpとdown:
質問:つまり、これはMain
関数をasync
としてマークする必要があるということですか?
まあそれはできませんコンパイルエラーがあるからです:
エントリポイントを「async」修飾子でマークすることはできません
非同期のものを理解している場合、スレッドはMain
関数に入ります----> SumTwoOperationsAsync
---->両方の関数を呼び出して、アウトになります。しかし、SumTwoOperationsAsync
まで
私は何が欠けていますか?
ほとんどのプロジェクトタイプでは、async
の "up"および "down"は、async void
イベントハンドラーで終了するか、フレームワークにTask
を返します。
ただし、コンソールアプリはこれをサポートしていません。
返されたタスクに対してWait
を実行するだけです:
static void Main()
{
MainAsync().Wait();
// or, if you want to avoid exceptions being wrapped into AggregateException:
// MainAsync().GetAwaiter().GetResult();
}
static async Task MainAsync()
{
...
}
または 私が書いたような独自のコンテキストを使用 :
static void Main()
{
AsyncContext.Run(() => MainAsync());
}
static async Task MainAsync()
{
...
}
async
Consoleアプリの詳細は 私のブログ です。
これを行う最も簡単な方法は次のとおりです
static void Main(string[] args)
{
Task t = MainAsync(args);
t.Wait();
}
static async Task MainAsync(string[] args)
{
await ...
}
迅速かつ非常に範囲の広いソリューションとして:
Task.ResultとTask.Waitの両方では、I/Oを使用する場合、I/Oが終了するのを待っている呼び出しスレッドがブロックされたままになるため、スケーラビリティを改善できません。
不完全なタスクで.Resultを呼び出すと、メソッドを実行するスレッドは座ってタスクの完了を待機する必要があり、その間スレッドは他の有用な作業を実行できなくなります。これは、タスクの非同期性の利点を無効にします。
私の解決策。 JSONServerは、コンソールウィンドウでHttpListenerサーバーを実行するために作成したクラスです。
class Program
{
public static JSONServer srv = null;
static void Main(string[] args)
{
Console.WriteLine("NLPS Core Server");
srv = new JSONServer(100);
srv.Start();
InputLoopProcessor();
while(srv.IsRunning)
{
Thread.Sleep(250);
}
}
private static async Task InputLoopProcessor()
{
string line = "";
Console.WriteLine("Core NLPS Server: Started on port 8080. " + DateTime.Now);
while(line != "quit")
{
Console.Write(": ");
line = Console.ReadLine().ToLower();
Console.WriteLine(line);
if(line == "?" || line == "help")
{
Console.WriteLine("Core NLPS Server Help");
Console.WriteLine(" ? or help: Show this help.");
Console.WriteLine(" quit: Stop the server.");
}
}
srv.Stop();
Console.WriteLine("Core Processor done at " + DateTime.Now);
}
}