c# - 异步方法中的 StringBuilder

标签 c# visual-studio-2010 .net-4.5 async-await

如果我触发多个异步 Web 请求,将结果附加到全局变量(例如 StringBuilder)是否安全?我知道不能保证顺序。

  1. 这会导致很多 Task 阻塞吗?

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

最佳答案

Does this cause a lot of Task blocking?

没有。您将等待所有任务完成,但这是设计使然。否则,这是一种相当有效的编写方式。

Is this safe?

这不安全。如 StringBuilder 中所述:“不保证任何实例成员都是线程安全的。” (在这种情况下,Append 是一个实例方法。)

由于您是在控制台应用程序中运行它,因此追加调用将发生在单独的线程上。您需要某种形式的同步,例如在 Append 调用周围使用 lock 语句。

请注意,如果您要在 Windows 窗体或 WPF 应用程序中使用相同的代码,则在 await 之后运行的代码将使用初始 SynchronizationContext,这会导致它始终在 UI 线程上运行,因此您不会遇到线程同步问题。但是,由于它在控制台应用程序中,延续将在单独的线程上运行。

关于c# - 异步方法中的 StringBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12980932/

相关文章:

C# 加速字符串?

c# - 如何在c#中使用UNION

visual-studio-2010 - Visual Studio在单个文件中的静态构造函数上崩溃…[VS2010]

WPF 编程方法论

entity-framework-6 - 替换 Entity Framework 6 中的自跟踪实体

转换/不转换时 C# 无限值错误

c# - 如何在 C# 中的 ComboBox 中仅显示项目的子字符串

c++ - CUDA 多线程 : __threadfence not preventing multiple threads from accessing resource

visual-studio-2010 - Visual Studio 2010 中的代码度量

c# - 适当的类似列表的排序数据结构