- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 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 R2
和 Visual 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/
C# 中单次自旋有多长?我想知道的是有一个 ManualResetEventSlim 有一个 spinCount 参数,我想知道每次旋转的时间(以毫秒为单位)或者它是如何工作的?我知道旋转对于短等待比
ManualResetEventSlim 状态的 MSDN 文档 You can use this class for better performance than ManualResetEvent
我正在尝试使用 ManualResetEventSlim 类在几个并行任务之间进行通信。 这是代码的简化版本: class Program { private static void Main
我正在阅读 ManualResetEventSlim's Reference . 它说的是什么意思: A common use of MRES.WaitHandle is to use MRES as
从 NET 4 开始,我可以使用 ManualResetEventSlim 类,它在阻塞之前稍微旋转一下,以便在阻塞时间很短的情况下获得时间优化(我没有上下文切换)。 我想使用基准来衡量这次的时间有多
给定以下代码: CancellationTokenSource cts = new CancellationTokenSource(); ManualResetEventSlim mre = new
ManualResetEventSlim:调用 .Set() 后立即调用 .Reset() 不会释放任何等待线程 (注意:ManualResetEvent 也会发生这种情况,而不仅仅是 ManualR
我是一名优秀的程序员,十分优秀!