3

複数の非同期 Web リクエストを開始した場合、結果を などのグローバル変数に追加しても安全StringBuilderですか? 注文が保証されていないことを知っています。

  1. これにより、多くのタスクのブロックが発生しますか?

  2. これは安全ですか?

private static StringBuilder sb = new StringBuilder();

private static async Task AccessTheWebAsync()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync(@"http://www.google.com/");
    sb.Append(response.StatusCode).Append(Environment.NewLine);        
}

static void Main(string[] args)
{
    List<Task> tasks = new List<Task>();
    for (int i = 0; i < 10; i++)
        tasks.Add(AccessTheWebAsync());
    Task.WaitAll(tasks.ToArray());
    Console.Write(sb.ToString());
    Console.ReadLine();
}
4

1 に答える 1

5

これにより、多くのタスクのブロックが発生しますか?

いいえ。すべてのタスクが完了するまで待機しますが、これは仕様によるものです。それ以外の場合、これはこれを記述するかなり効率的な方法です。

これは安全ですか?

これは安全ではありません。StringBuilderに記載されているように、 「インスタンスメンバーはスレッドセーフであることが保証されていません。」(この場合、Appendはインスタンス メソッドです。)

これをコンソール アプリケーションで実行しているため、Append 呼び出しは別のスレッドで発生します。呼び出しlockの前後にステートメントを使用するなど、何らかの形式の同期が必要です。Append

ただし、この同じコードを Windows フォームまたは WPF アプリケーションで使用する場合、後で実行さawaitれるコードは initial を使用してスケジュールされるSynchronizationContextため、常に UI スレッドで実行されることに注意してください。スレッド同期の問題があります。ただし、これはコンソール アプリケーションであるため、継続は別のスレッドで実行されます。

于 2012-10-19T19:15:58.893 に答える