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 回答