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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 13:00:36  来源:igfitidea点击:

Any solution to Illegal Cross Thread Operation exception?

提问by gil

When you data bind in C#, the thread that changes the data causes the control to change too. But if this thread is not the one on which the control was created, you'll get an Illegal Cross Thread Operation exception.

在 C# 中进行数据绑定时,更改数据的线程也会导致控件发生更改。但是,如果该线程不是创建控件的线程,则会出现非法跨线程操作异常。

Is there anyway to prevent this?

有没有办法防止这种情况?

回答by Mike Stone

You should be able to do something like:

您应该能够执行以下操作:

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

InvokeRequired is a property on Controls to see if you are on the correct thread, then Invoke will invoke the delegate on the correct thread.

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

UPDATE: Actually, at my last job we did something like this:

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

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

    // Regular handling code
}

which removes the need for the else block and kind of tightens up the code.

这消除了对 else 块的需要,并收紧了代码。

回答by tags2k

As I don't have a test case to go from I can't guarantee this solution, but it seems to me that a scenario similar to the one used to update progress bars in different threads (use a delegate) would be suitable here.

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

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

public void DoDataBind()
{
    DataBind();
}

If the data binding needs to be done by a particular thread, then let that thread do the work!

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

回答by tags2k

If the thread call is "illegal" (i.e. the DataBind call affects controls that were not created in the thread it is being called from) then you need to create a delegate so that even if the decision / preparation for the DataBind is not done in the control-creating thread, any resultant modification of them (i.e. DataBind()) will be.

如果线程调用是“非法的”(即 DataBind 调用会影响不是在调用它的线程中创建的控件),那么您需要创建一个委托,以便即使 DataBind 的决定/准备没有在控件创建线程,它们的任何结果修改(即 DataBind())都将是。

You would call my code from the worker thread like so:

您可以像这样从工作线程调用我的代码:

this.BindData.Invoke();

This would then cause the original thread to do the binding, which (presuming it is the thread that created the controls) should work.

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

回答by Brian Leahy

In WPF and Silverlight the binding infrastructure takes care of the switching to the UI thread.

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