c# - UI Thread .Invoke() 导致句柄泄漏?

标签 c# memory-leaks multithreading handles

在什么情况下从非 UI 线程更新 UI 控件会导致进程的句柄不断增加,当使用委托(delegate)和 .InvokeRequired 时?

例如:

public delegate void DelegateUIUpdate();
private void UIUpdate()
{
    if (someControl.InvokeRequired)
    {
        someControl.Invoke(new DelegateUIUpdate(UIUpdate));
        return;
    }
    // do something with someControl
}

当在循环或定时器间隔中调用它时,程序的句柄会持续增加。

编辑:

如果上面的内容被注释掉并修改为:

public delegate void DelegateUIUpdate();
private void UIUpdate()
{
    //if (someControl.InvokeRequired)
    //{
    //   someControl.Invoke(new DelegateUIUpdate(UIUpdate));
    //    return;
    //}
    CheckForIllegalCrossThreadCalls = false;
    // do something with someControl
}

...然后句柄停止递增,但是我当然不想允许跨线程调用。

编辑 2:

这是一个显示句柄增加的示例:

Thread thread;
private delegate void UpdateGUI();
bool UpdateTheGui = false;

public Form1()
{
    InitializeComponent();

    thread = new Thread(new ThreadStart(MyThreadLoop));
    thread.Start();
}

private void MyThreadLoop()
{
    while (true)
    {
        Thread.Sleep(500);
        if (UpdateTheGui)
        {
            UpdateTheGui = false;
            UpdateTheGuiNow();
        }
    }
}

private void UpdateTheGuiNow()
{
    if (label1.InvokeRequired)
    {
        label1.Invoke(new UpdateGUI(UpdateTheGuiNow));
        return;
    }

    label1.Text = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss");
    label2.Text = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss");
    label3.Text = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss");
}

private void btnInvoke_Click(object sender, EventArgs e)
{
    UpdateTheGui = true;
}

最佳答案

我遇到了同样的问题

this.Invoke(new DelegateClockUpdate(ChangeClock), sender, e);

每次调用创建一个句柄。

句柄递增,因为 Invoke 是同步的,实际上句柄一直悬空。

应使用等待句柄来处理结果或异步 BeginInvoke 方法,如下所示。

this.BeginInvoke(new DelegateClockUpdate(ChangeClock), sender, e);    

关于c# - UI Thread .Invoke() 导致句柄泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3048430/

相关文章:

java - 第二个线程在 for 循环中不运行()

c# - 这种类型的 C# 编码语法称为什么,它在做什么?

c# - 表单设计器 View 在 Visual Studio 2019 C# CMake 项目中不可用

c# - 如何在 ASP.NET 中使 List 变量常量

iPhone SDK : [MobileOfferViewController _shouldUseKeyWindowStack]

java - Kafka堆外内存泄漏

c# - 通过 JavaScript 从 C# 向 DIV 添加值

c# - COM C# 内存泄漏跟踪

c# - ThreadStart with Parameter 方法

iphone - 将 iOS 上的 printf 重定向到用户界面