私は現在、Webサイト上のさまざまな画像を指す多数のURLを生成し、WebClient.DownloadDataAsync()
を使用してバイトストリームとしてダウンロードするC#コンソールアプリを作成しています。
私の問題は、最初の非同期呼び出しが行われると、コンソールアプリはプログラムが完了したと見なし、非同期呼び出しが戻る前に終了することです。 Console.Read()
を使用することで、コンソールを強制的に開いたままにすることができますが、これはあまり良い設計ではないようです。さらに、プロセス中に(コンソールが入力を待機している間に)ユーザーがEnterキーを押すと、プログラムは終了します。
非同期呼び出しが戻るのを待っている間にコンソールが閉じないようにするためのより良い方法はありますか?
編集:ダウンロードが行われている間、コンソールを介してユーザーにステータスインジケーターを提供しているため、呼び出しは非同期です。
はい。 ManualResetEvent を使用し、非同期コールバックでevent.Set()
を呼び出します。メインルーチンがevent.WaitOne()
でブロックした場合、非同期コードが完了するまで終了しません。
基本的な擬似コードは次のようになります。
static ManualResetEvent resetEvent = new ManualResetEvent(false);
static void Main()
{
CallAsyncMethod();
resetEvent.WaitOne(); // Blocks until "set"
}
void DownloadDataCallback()
{
// Do your processing on completion...
resetEvent.Set(); // Allow the program to exit
}
もう1つのオプションは、非同期Mainメソッドを呼び出して、返されるタスクを待つことです。
_static void Main(string[] args)
{
MainAsync(args).Wait();
}
static async Task MainAsync(string[] args)
{
// .. code goes here
}
_
.NET 4.5以降、GetAwaiter().GetResult()
を呼び出すことができるようになりました
_static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
_
アプリケーションが実行しているのがそれだけの場合は、非同期呼び出しを除外することをお勧めします。具体的にはwantダウンロードが完了するまでアプリを「ハング」させるため、非同期操作の使用は、特にコンソールアプリでは、ここで必要なこととは逆になります。
C#7.1では、Main
をasync
としてマークできるようになったことを述べておく必要があります。
static async Task Main()
{
await LongRunningOperation();
}