InvokeRequired = true但BeginInvoke失败导致冻结

时间:2016-05-02 18:35:00

标签: c# winforms begininvoke

C#windows形成VS 2013操作系统:Win7

我遇到一个有趣的问题,其中invokeRequired为true,但是当我调用beginInvoke()时,它永远不会执行,窗口永远不会关闭。

然而,当我完全删除了BeingInvoke()时,窗口关闭了。

     public void CloseMyForm()
            {
//if I remove this if block altogether including beingInvoke() the window closes ok
                if ( !this.IsDisposed && this.InvokeRequired && this.IsHandleCreated )
                {
                    log("callin begininvoke()"); //this is logged correctly 

                    this.BeginInvoke((MethodInvoker)delegate() { CloseMyForm(); });
                    return;
                }
               log("outside of begin invoke"); //this is never logged
               this.Close();
            }

CloseMyForm由一个单独的线程调用,该线程在启动时就像这样创建。请注意,这不是主窗口,而是从主窗体打开的单独窗口。

Thread connectThread = new Thread(new ThreadStart(CheckWhenToCloseMyForm)); 

    public void CheckWhenToCloseMyForm()
    {
        while (true)
        {
            CallSomeFunc();
            CallSomeFunc1();
            if (allconditionsmet)
            {
                System.Threading.Thread.Sleep(1000);
                CloseMyForm();
break;

            }        
        }       
    }

2 个答案:

答案 0 :(得分:2)

BeginInvoke通过基础Control类提供。

  

在创建控件的底层句柄的线程上异步执行委托

如果InvokedRequired属性实际为true,则表示"调用方必须在对控件进行方法调用时调用invoke方法,因为调用方所在的线程与创建控件的线程不同上"

看起来您错误地调用了BeginInvoke,您应该尝试拨打Invoke

  

在拥有控件底层窗口句柄的线程上执行指定的委托

public void CloseMyForm()
{
    if (!this.IsDisposed && this.InvokeRequired && this.IsHandleCreated)
    {
        log("calling invoke()");
        this.Invoke((MethodInvoker)delegate() { CloseMyForm(); });
    }
    else
    {
        log("outside of invoke"); // this is never logged
        this.Close();
    }
}

查看有助于简化此操作的this neat little extension method。有了这个,您可以编写这样的close方法。

public void CloseMyForm()
{
    this.ThreadSafeInvoke(() => this.Close());
}

答案 1 :(得分:0)

好的,既然你提供了这个片段,我就明白了这个问题。

Thread connectThread = new Thread(new ThreadStart(CheckWhenToCloseMyForm)); 

public void CheckWhenToCloseMyForm()
{
    while (true)
    {
        CallSomeFunc();
        CallSomeFunc1();
        if (allconditionsmet)
        {
            System.Threading.Thread.Sleep(1000);
            CloseMyForm()
        }        
    }       
}

while循环中,您需要breakreturn,然后才能调用CloseMyForm。就是这样......非常简单。您可以使用BeginInvokeInvoke