39

私は現在、Webサイト上のさまざまな画像を指す多数のURLを生成し、を使用してバイトストリームとしてダウンロードするC#コンソールアプリを作成していますWebClient.DownloadDataAsync()

私の問題は、最初の非同期呼び出しが行われると、コンソールアプリはプログラムが完了したと見なし、非同期呼び出しが戻る前に終了することです。Iを使用するConsole.Read()ことで、コンソールを強制的に開いたままにすることができますが、これはあまり良いデザインではないようです。さらに、プロセス中に(コンソールが入力を待機している間に)ユーザーがEnterキーを押すと、プログラムは終了します。

非同期呼び出しが戻るのを待っている間にコンソールが閉じないようにするためのより良い方法はありますか?

編集:ダウンロードが行われている間、コンソールを介してユーザーにステータスインジケーターを提供しているため、呼び出しは非同期です。

4

4 に答える 4

52

はい。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
}
于 2010-10-01T15:48:51.447 に答える
28

もう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();
}

.Wait()と.GetAwaiter()。GetResult()の違いは何ですか?

于 2013-01-29T03:10:36.700 に答える
6

アプリケーションが実行しているのがそれだけの場合は、非同期呼び出しを除外することをお勧めします。特に、ダウンロードが完了するまでアプリを「ハング」させたいので、非同期操作を使用することは、特にコンソールアプリでは、ここで必要なこととは逆になります。

于 2010-10-01T15:49:32.460 に答える
1

MainC#7.1では、としてマークを付けることができるようになったことを述べておく必要がありますasync

static async Task Main()
{
  await LongRunningOperation();
}
于 2018-06-11T15:08:13.563 に答える