c# - 连接调试器时,带有 Task.Run 的代码会更改输出

标签 c# debugging task-parallel-library

我有以下示例程序:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace StackoverflowExample
{
    class Program
    {
        static int value = 1;
        static void Main(string[] args)
        {
            Task t1 = Task.Run(() =>
            {
                if (value == 1)
                {
                    Thread.Sleep(1000);
                    value = 2;
                }
            });

            Task t2 = Task.Run(() =>
            {
                value = 3;
            });

            Task.WaitAll(t1, t2);
            Console.WriteLine(value);
            Console.ReadLine();
        }
    }
}

我希望这段代码输出2。我认为 t1 会看到值为 1,然后休眠一秒钟,在此期间 t2 将值设置为 3,然后 t1 将其更改回 2

这是附加调试器时发生的行为(在 Visual Studio 中按 F5)。但是,当我在没有附加调试器的情况下运行此程序(在 Visual Studio 中按 Ctrl + F5)时,输出为 3

为什么?

最佳答案

t2 没有理由不能在 t1 之前开始运行。使用 TPL 库,这种情况甚至更可能发生(任务首先推送到 LIFO 堆栈上)。

调试器可以延迟/改变足以产生另一个结果的事情。

任务和线程通常会以这种方式产生误导。

关于c# - 连接调试器时,带有 Task.Run 的代码会更改输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17813933/

相关文章:

debugging - 如何重现偶尔发生的错误?

c# - await 关键字可以生成并行代码吗?

.net - 从方法中将 BlockingCollection 作为 IEnumerable 返回

c# - 带有路由 id 参数的 Html.BeginForm 并在提交时获取参数?

c# - 如何将输入值绑定(bind)到 Blazor 中的对象属性

c# - 如何检查设定时间是否等于系统时间

c# - 使用 PLINQ 计算阶乘的递归函数

c# - 在 C# 中使用通知的生产者和消费者

C++:用于调试的类的字符串表示形式

android - 我可以从我的应用程序触发 Android 的内置错误捕获功能吗?