gpt4 book ai didi

c# - ManualResetEventSlim.Set() 并不总是解锁任务内的等待

转载 作者:行者123 更新时间:2023-11-30 12:55:42 27 4
gpt4 key购买 nike

我正在尝试使用 ManualResetEventSlim 类在几个并行任务之间进行通信。

这是代码的简化版本:

class Program
{
private static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();

ManualResetEventSlim eventSlim = new ManualResetEventSlim(false);

Task.Run(() =>
{
Task.Run(() =>
{
Thread.Sleep(1000);

eventSlim.Set();
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Task! {stopwatch.Elapsed}");
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Main thread! {stopwatch.Elapsed}");

stopwatch.Stop();

Console.ReadLine();
}
}

大多数时候代码运行良好并输出:

Hello from main thread! 00:00:01.1017591
Hello from task! 00:00:01.1017630

然而,每五六次我运行代码一次,我只得到这个输出:

Hello from main thread! 00:00:01.1017591

而且 Task 中 Wait 之后的代码永远不会被调用。

我在 Windows Server 2012 R2Visual Studio 15.4.1 上使用 .NET Core 2.0.2

任何人都可以重现这种行为吗?

任何人都可以确认我的代码是否正确或者是否有任何问题?

更新在@ArhiChief建议在Release配置中测试结果后,我发现问题只有在我使用IDE调试代码时才会出现。

当我在调试/发布配置的命令行中构建和运行代码时,似乎没有问题。

我尝试关闭/重新打开 IDE 并清理项目并重新构建,现在 IDE 似乎也能正常工作。

结果:在重新启动 IDE、清理项目并重新构建项目后,到目前为止我还没有遇到这个问题。我怀疑 IDE 中存在一个小错误。但是我不能报告它,因为它现在已经消失了。

我将此问题悬而未决,以防其他人遇到此问题并希望跟踪和报告错误。

最佳答案

我也知道您的第一个任务可能会被处理和收集。考虑这段代码

static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();

ManualResetEventSlim eventSlim = new ManualResetEventSlim(false);

Task.Run(() =>
{
Task.Run(() =>
{
Thread.Sleep(1000);

eventSlim.Set();
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Task! {stopwatch.Elapsed}");
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Main thread! {stopwatch.Elapsed}");

stopwatch.Stop();

//Console.ReadLine();
}

我从主线程收到消息 Hello! 00:00:01.0111623。我也看过了

A single call to Set() signals the event, and any waiting Tasks are released. New calls to Wait() don't block until Reset() method called.

但让我们回到我们的代码。如果你这样重写它

static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();

ManualResetEventSlim eventSlim = new ManualResetEventSlim(false);

var t = Task.Run(() =>
{
Task.Run(() =>
{
Thread.Sleep(1000);

eventSlim.Set();
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Task! {stopwatch.Elapsed}");
});

eventSlim.Wait();

Console.WriteLine($"Hello from the Main thread! {stopwatch.Elapsed}");

stopwatch.Stop();

t.Wait();
//Console.ReadLine();
}

你会发现一切都如你所愿。

关于c# - ManualResetEventSlim.Set() 并不总是解锁任务内的等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46886385/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com