BeginInvoke未被执行

时间:2017-01-12 16:00:56

标签: c# .net winforms

我在 Windows窗体上有下一个代码:

if (control.IsHandleCreated)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(action);
    }
    else
    {
        action.Invoke();
    }
 }

调试,它进入InvokeRequired = false并且它完美运行,但在生产环境中。它以某种方式进入InvokeRequired = true,因此它应该执行BeginInvoke()方法。

没有。它永远不会进入行动。此脚本属于 DataGrid 控件,但在同一表单上的不同 DataGrids Comboboxes 等上具有相同的功能;所以它似乎是这个 DataGrid 特有的东西。 有什么想法吗?

由于

3 个答案:

答案 0 :(得分:1)

我试图找到真正的答案,我的猜测是,当您调用begininvoke时,一条消息被放入该线程的队列中。该线程将项目从此队列中取出,并按1对其进行处理。比方说,您调用BeginInvoke的速度快于处理线程可以处理的速度...您的队列将变得越来越大,并且需要越来越多的时间来处理。那么主线程可能在执行其他操作时被阻塞。当您的线程正在执行其他操作时,它将不会处理队列外的项目,因此线程无法访问控件。 我测试了您的代码,如果缺少访问权限,则代码无法重复,然后我更改了代码,并在重复一两次后可以正常工作:

int i = 0;
    public delegate void AsyncMethodCaller();
    private  void proc2()
    {
        Action action = () => control1.Text = (i += 1).ToString();

        if (control1.IsHandleCreated)
        {
            if (control1.InvokeRequired)
            {
                control1.BeginInvoke(new AsyncMethodCaller(proc2));
            }
            else
            {
                action.Invoke();
            }
        }
        else
        {
            MessageBox.Show("Handle creation error");
        }
    }

    private void proc1()
    {
        for (int i=0; i<1000; i++)
        {
            //do something
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread1 = new Thread(proc1);
        thread1.Start();

        Thread thread2 = new Thread(proc2);
        thread2.Start();
    }

答案 1 :(得分:0)

您必须使用以下内容:

public static void action() 
     {
        if (varControl.InvokeRequired)
        {
            //Seems following code is better than BeginInvoke().
            varControl.Invoke(new MethodInvoker(() => action()));

        } 
        else 
        {
            //your code
        }

     }

我喜欢以下不需要委托的代码,并且仅在需要调用时才使用invoke:

        MethodInvoker invoker =new MethodInvoker (action);
        if (varControl.InvokeRequired)
        {
            varControl.Invoke(invoker); 
            //I think that Invoke() is better than BeginInvoke()
        } 
        else 
        {
            invoker.Invoke();
            //SomeTimes BeginInvoke() not works correctly,
            //and you have to use Invoke().

        }

答案 2 :(得分:0)

这就是我刚刚使用的:

<your control>.Invoke(new MethodInvoker(delegate () {
   … do your work here
}));

-吉娜