Control.Invoke()挂起应用程序

Dan*_*lba 9 .net c# multithreading winforms

我正在控制加载数据时显示动画.线程完成后,我隐藏动画并显示控件.所以我从一个线程执行这个代码:

protected void InvokeEnableBackControl()
{
    if (this.InvokeRequired)
    {                
        this.Invoke(new OpHandler(EnableBackControl));
    }
    else
    {
        EnableBackControl();
    }
}
Run Code Online (Sandbox Code Playgroud)

有时,当我执行此代码时,主线程在以下代码中被挂起:

protected virtual void EnableBackControl()
{
    if (overlayAnimation.TargetControl != null)
    {
        overlayAnimation.TargetControl.BringToFront();
    }

    overlayAnimation.SendToBack();
    overlayAnimation.Enabled = false;
    overlayAnimation.Visible = false;                      
Run Code Online (Sandbox Code Playgroud)

}

我不确定它是否被绞死设置EnableVisible属性.您是否知道任何可能会将应用程序调用这些属性的情况Control.Invoke

ben*_*sai 17

注意Control.Invoke是同步的,所以它会等待EnableBackControl()返回.考虑使用Control.BeginInvoke,你可以"发射并忘记".

看到这个答案:Invoke()和BeginInvoke()之间有什么区别


Sql*_*yan 7

我在执行之前遇到了问题.当我的主线程仍然忙时,在后台线程上调用 - 这给人的印象是应用程序挂起,因为.Invoke只是坐在那里,等待主线程到回应它正在关注.可能的原因:

  • 您的主线程被阻止等待某事
  • 您的主表单目前有一个模态对话框,因此它不会收听新请求
  • 您的主要线程正在旋转,要么不断检查某些内容是否已完成或正在进行新的工作.在我的情况下,主线程花了第一分钟在紧密循环中旋转后台线程,因此它没有侦听来自后台线程的任何.Invoke请求.

当您附加调试器时,请特别注意您的主控制MessagePump线程正在做什么 - 我怀疑它缺乏关注是您的麻烦的原因.如果你发现它是主线程中没有响应的紧密循环,请尝试.DoEvents在循环中插入一个,这将暂停执行并强制主线程清空消息泵并路由任何未完成的请求.