非法跨线程操作异常的任何解决方案?

当您在C#中进行数据绑定时,更改数据的线程也会导致控件更改。但是如果这个线程不是创建控件的线程,那么你会得到一个非法的跨线程操作异常。

无论如何要防止这一点?

0

5 答案

你应该能够做到这样的事情:

if (control.InvokeRequired)
{
    control.Invoke(delegateWithMyCode);
}
else
{
    delegateWithMyCode();
}

InvokeRequired是Controls上的一个属性,用于查看您是否在正确的线程上,然后Invoke将在正确的线程上调用委托。

更新:其实,在我上一份工作中,我们做了这样的事情:

private void SomeEventHandler(Object someParam)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
    }

    // Regular handling code
}

这消除了对else块的需求,并且使代码更紧密。

0
额外

由于我没有测试用例,我不能保证这个解决方案,但在我看来,类似于用于更新不同线程(使用委托)的进度条的场景在这里似乎是适合的。

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
    DataBind();
}

如果数据绑定需要由特定线程完成,那么让该线程完成工作!

0
额外

如果线程调用是“非法”的(例如,DataBind调用会影响未在线程中创建的控件,则它将被调用),则需要创建一个委托,以便即使DataBind的决策/准备工作未在控制创建线程,它们的任何结果修改(即DataBind())将是。

你会从工作线程调用我的代码,如下所示:

this.BindData.Invoke();

这会导致原始线程执行绑定,它(假设它是创建控件的线程)应该可以工作。

0
额外

如果数据修改不是太耗时(也就是说,如果后台线程的主要目的不是实际的数据修改),请尝试将修改数据的部分移至代表并调用该代理。

如果实际繁重工作在数据上,您可能必须创建此数据的深层副本以传递给后台线程,后台线程会再次通过Invoke将处理后的数据发送回UI线程。

您只需将将更改数据的代码移动到委托函数中(因为数据更改触发了控件更新)。除此之外,你不应该写任何额外的东西。

0
额外

在WPF和Silverlight中,绑定基础架构负责切换到UI线程。

0
额外