gpt4 book ai didi

c# - IProgress 未触发

转载 作者:行者123 更新时间:2023-11-30 20:46:29 25 4
gpt4 key购买 nike

我有以下代码片段:

var progress = new Progress<string>();
var count = 0;
progress.ProgressChanged += (o, transferProgress) => ++count;
for (var i = 0; i < 10; i++)
{
((IProgress<string>)progress).Report(i.ToString(CultureInfo.InvariantCulture));
}
Console.WriteLine(count);

在这种情况下,count 变量永远不会递增。这是为什么?

更新:这些事件似乎正在发生,但它们只是“迟到了”(正如下面一些人所指出的)。为了提供更多上下文,这段代码被放置在按钮单击事件处理程序中的 Win Forms 应用程序中。无论我在处理程序中做了什么(即休眠 x 秒),直到按钮单击处理程序未完成执行事件都不会触发。我怎样才能解决这个问题以获得“及时”的事件?

最佳答案

来自 Progress<T> documentation :

Any handler provided to the constructor or event handlers registered with the ProgressChanged event are invoked through a SynchronizationContext instance captured when the instance is constructed. If there is no current SynchronizationContext at the time of construction, the callbacks will be invoked on the ThreadPool.

这里可能发生的情况是您确实有一个同步上下文,因此回调会被延迟到一段时间后,具体取决于控制此代码执行的特定同步上下文的行为。

请注意,即使您没有在同步上下文中运行,也不能保证 count == 10在循环体之后,因为线程池可能还没有执行所有的回调。

此外,由于未声明变量 volatile当前线程可能不会观察到另一个线程所做的更改,因为允许运行时/JIT 缓存在单线程上下文中不可能更改的值。为了安全起见,您还想使用 Interlocked.Increment(ref count)在回调内部,以防两个回调同时执行,因为 ++count不是原子操作。 (这仅在通过线程池分派(dispatch)回调时才有意义。)

tl;dr 版本是“欢迎使用并发”。

关于c# - IProgress<T> 未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26851573/

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