3

Async と Await を使用した非同期プログラミング (C# と Visual Basic) を読んだ後、GUI がハングしないことを期待しています。

    public async Task<string> DoBusyJob()
    {
        // Busy Job
        Thread.Sleep(10000);
        i++;
        return "Finished " + i;
    }

    int i = 0;

    private async void button1_Click(object sender, EventArgs e)
    {
        // Hang!
        string result = await DoBusyJob();

        this.label1.Text = result;
    }

そうではありません。それはまだハングアップします。さらに追加する必要があることに気づきawaitましたDoBusyJob

    public async Task<string> DoBusyJob()
    {
        // Busy Job
        await Thread.Sleep(10000);
        i++;
        return "Finished " + i;
    }

    int i = 0;

    private async void button1_Click(object sender, EventArgs e)
    {
        // OK!
        string result = await DoBusyJob();

        this.label1.Text = result;
    }

なぜそうなのか、私は知っていますか?本当にdouble awaitが必要ですか? 次の場合はどうなりますか?

    public async Task<string> DoBusyJob()
    {
        // How to prevent Hang?
        for (int j = 0; j < 10000000; j++) {
            double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
        }
        i++;
        return "Finished " + i;
    }

    int i = 0;

    private async void button1_Click(object sender, EventArgs e)
    {
        // Hang!
        string result = await DoBusyJob();

        this.label1.Text = result;
    }
4

3 に答える 3

6

メソッドに関しては、この質問に対する優れた回答をご覧ください。async

すでに非同期のメソッドasyncを使用していない場合、メソッドの実行を非同期にするには、追加するだけでは不十分です。awaitその場合、Taskたとえば、作業の実行を表すインスタンスを返す必要があります。を呼び出すことによってTask.Factory.StartNew

于 2012-10-18T04:17:36.933 に答える
2

async/ awaitFAQに優れた回答があります。

Q. メソッドで「async」キーワードを使用すると、そのメソッドのすべての呼び出しが非同期になりますか?

A. いいえ。「async」とマークされたメソッドを呼び出すと、現在のスレッドで同期的に実行されます...

Q.「async」キーワードにより、メソッドの呼び出しが ThreadPool のキューに入れられますか? 新しいスレッドを作成するには? 火星にロケット船を打ち上げるには?

A.いいえ、いいえ、いいえ...

私のasync/awaitイントロが役に立つかもしれません。

于 2012-10-18T13:17:12.233 に答える
0

// OK!に追加 awaitする 際にあなたのことを理解していただければ幸いです メソッドが戻るThread.Sleep(10000);
のを待つことは不可能です メソッドの署名または戻り値の型を 指定することだけを待つことができますSleep()void
TaskTask<TResult>

非同期メソッドは非同期で (またはそれまで) 実行されるawaitため、ブロッキング UI スレッド
await Task.Run() はすぐに (前の) UI 同期コンテキストに戻る必要があります。つまり、次の i++ を続行します。ライン実行

public async Task<string> DoBusyJob()
{
  // Busy Job

  await Task.Run(() =>
    {
        for (int j = 0; j < 10000000; j++)
        {
            double m = Math.Sqrt(1) + Math.Sqrt(2) + Math.Sqrt(3);
        }
    }
                );
  i++;
  return "Finished " + i;
}
于 2013-05-05T18:30:37.747 に答える