0

非同期CTPを使用していくつかのプローブを作成していますが、GUIがブロックされているため、良い結果が得られません。

ボタンとログ用のテキストボックスを備えたWPFアプリケーションがあります。それから私はこのコードを持っています:

private async void btnAsync01_Click(object sender, RoutedEventArgs e)
        {
            UpdateTxtLog("Enter in Button Async01: " + System.DateTime.Now);
            await metodo01Async();
            UpdateTxtLog("Exit button Async01: " + System.DateTime.Now);
        }

private async Task slowMethodAsync()
        {
            UpdateTxtLog("Enter in slowMethod: " + System.DateTime.Now);
            Thread.Sleep(5000);
            UpdateTxtLog("Exit slowMethod: " + System.DateTime.Now);
        }

間違っていない場合は、「sync」(この場合はクリックイベント)でメソッドを設定します。メソッドはawaitを使用して、実行ポイントを実際のメソッドを呼び出すメソッドに戻し、実行はGUIに戻ります。 。

したがって、GUIでボタンをクリックし、クリックイベントでslowMethodを待機します。slowMethodでawaitを使用する方法では、コントロールがGUIに返され、GUIがブロックされないようにする必要があります。ただし、GUIはブロックされ、slowMethodが終了するまでtxtLogには情報が表示されません。

これは、slowMethodがGUIと同じスレッドで実行されるためですか?私が間違っている場合、非同期では通常、awaitメソッドを呼び出すメソッドと同じスレッドを使用しますが、非同期の理由はこれを回避すると思います。

thread.SleepなしでslowMethodをシミュレートするにはどうすればよいですか?おそらくこれが問題です。slowMethodではスレッドをスリープ状態にし、slowMethodのスレッドはGUIと同じだからです。

これにより、非同期メソッドのコードを他のスレッドで実行することが常に推奨されていると思いますか?これが正しければ、メインスレッドをブロックしないためにタスクを使用する必要がある場合、非同期を使用する意味はどれですか?

いつ非同期を使用し、いつタスクを使用するのですか?

このプローブについては、次のWebの例に従っています:http://www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern

この例では、slowMethodとしてclient.DownloadStringTaskAsyncを使用していますが、私の場合、WebClientを使用する代わりに、slowMethodをシミュレートするためにスリープを使用したダミーメソッドを使用しています。それがユニークな違いだと思います。

ありがとう。ダイムロック。

4

1 に答える 1

2

非同期スリープ/遅延await TaskEx.Delay(5000)を実行するを使用して待機をシミュレートします。

async/についてもう少し読んでみることもできますawait。Channel9の優れたビデオがいくつかあります。Stephen Toub、Eric Lippert、および他の多くのMicrosoftブロガーは、優れた概要を持っています。Jon Skeetの「eduasync」ブログシリーズは、本当に深く掘り下げるのにも適しています。他の多くの人と同じように、私は自分のブログに非同期イントロを書きました。

async簡単に言うと、await実際にどのように機能するかを次に示します。

  • キーワードはasyncキーワードのみを有効にしawaitます。以上です。バックグラウンドスレッドではメソッドを実行しません。
  • awaitその「待機者」が完了していない場合にのみ非同期的に動作します。

したがって、あなたの場合、btnAsync01_Click両方slowMethodAsyncともUIスレッドで実行されます。slowMethodAsync同期的に実行され(実行中Thread.Sleep)、次にに戻りbtnAsync01_Clickます。これは、すでに完了したタスクを待機します。タスクはすでに完了しbtnAsync01_Clickているため、UIメッセージループに屈することなく実行を続行します。

に置き換えるThread.Sleepawait TaskEx.DelaybtnAsync01_ClickはUIスレッドでの実行を開始し、を呼び出しますslowMethodAsync(UIスレッドでも実行されます)。sが遅延(完了していない)の場合slowMethodAsync await、不完全なタスクをに返しますbtnAsync01_ClickbtnAsync01_Clickそのタスク(完了していません)が実行さawaitれ、UIループに戻ります。

遅延が期限切れになると、遅延は完了し、slowMethodAsync再開します(UIスレッド上)。slowMethodAsync完了すると、返されたタスクが完了し、(btnAsync01_ClickUIスレッドで)再開します。

于 2012-04-07T16:59:38.500 に答える