gpt4 book ai didi

c# - 从 System.Threading.Timer 在 UI 中调用时如何避免泄漏句柄?

转载 作者:太空狗 更新时间:2023-10-29 18:28:25 25 4
gpt4 key购买 nike

似乎在 System.Threading.Timer 的回调中调用 winforms 控件上的 Invoke 会泄漏句柄,直到计时器被释放。有谁知道如何解决这个问题?我需要每秒轮询一个值并相应地更新 UI。

我在一个测试项目中进行了尝试,以确保这确实是泄漏的原因,简单来说就是:

    System.Threading.Timer timer;
public Form1()
{
InitializeComponent();
timer = new System.Threading.Timer(new System.Threading.TimerCallback(DoStuff), null, 0, 500);
}
void DoStuff(object o)
{
this.Invoke(new Action(() => this.Text = "hello world"));
}

如果您在 Windows 任务管理器中观察,这将泄漏 2 个句柄/秒。

最佳答案

Invoke 的作用类似于 BeginInvoke/EndInvoke 对,因为它将消息发布到 UI 线程,创建句柄,并等待该句柄以确定 Invoked 方法何时完成。正是这个句柄“漏水”了。您可以使用 Process Explorer 看到这些是未命名的事件在应用程序运行时监视句柄。

如果 IASyncResult 是 IDisposable,对象的处置将负责清理句柄。实际上,当垃圾收集器运行并调用 IASyncResult 对象的终结器时,句柄会被清理。您可以通过在每 20 次调用 DoStuff 之后添加一个 GC.Collect() 来看到这一点——句柄计数每 20 秒下降一次。当然,通过添加对 GC.Collect() 的调用来“解决”问题是解决问题的错误方法;让垃圾收集器完成它自己的工作。

如果您不需要 Invoke 调用是同步的,请使用 BeginInvoke 而不是 Invoke,并且不要调用 EndInvoke;最终结果将做同样的事情,但不会创建或“泄漏”句柄。

关于c# - 从 System.Threading.Timer 在 UI 中调用时如何避免泄漏句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1603123/

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