c# - Task<T>.Result 和字符串连接

标签 c# .net c#-5.0

我在玩 async/await 时遇到了以下问题:

class C
{
    private static string str;

    private static async Task<int> FooAsync()
    {
        str += "2";
        await Task.Delay(100);
        str += "4";
        return 5;
    }

    private static void Main(string[] args)
    {
        str = "1";
        var t = FooAsync();
        str += "3";

        str += t.Result; // Line X

        Console.WriteLine(str);
    }
}

我预计结果是“12345”,但结果是“1235”。不知何故,“4”被吃掉了。

如果我将 X 行拆分为:

int i = t.Result;
str += i;

然后是预期的“12345”结果。

为什么会这样? (使用VS2012)

最佳答案

Why is it so? (Using VS2012)

您在控制台应用程序中运行它,这意味着当前没有同步上下文。

因此,FooAsync() 的部分await 之后的方法在单独的线程中运行。当你做 str += t.Result你实际上在 += 4 之间制造了竞争条件打电话,然后 += t.Result .这是因为 string +=不是原子操作。

如果您要在 Windows 窗体或 WPF 应用程序中运行相同的代码,同步上下文将被捕获并用于 += "4" ,这意味着它们都将在同一个线程上运行,您不会看到这个问题。

关于c# - Task<T>.Result 和字符串连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16743371/

相关文章:

c# - MSHTML.dll - 如何确保在安装机器上使用一致版本的 IE 渲染引擎

c# - 如何在单元测试中等待后使用断点?

c# - XElement 在 C# 中使用 async/await 保存文件

c# - 即使在 .NET Core 控制台应用程序中使用 Console.ReadLine(),docker 容器也会立即退出

c# - ADAL.NET v3 不支持 AcquireToken 和 UserCredential?

c# - 获取错误 "there is no row at position 0"

C# 异步等待澄清?

c# - 在 C# 的对象列表中打印出 1 个对象

c# - 如何获取引用程序集的物理路径

.net - 为什么 'remoteCertificate' 参数在 LocalCertificateSelectionCallback 方法中为空?