我正在使用Parallel.Invoke运行繁重的后台工作,在所有处理完成后我返回方法,再次返回,调用下一个方法来利用计算出的数据我得到错误: 跨线程操作无效:控制''从创建它的线程以外的线程访问。
但是我已经从Parallel.Invoke创建的线程返回到首先调用它的线程。控件不会恢复到它启动的线程是否正常?我怎样才能确保这确实发生?
代码:
public void TopMethod()
{
Calculate(4);
UpdateGui();
}
public void Calculate(int depth)
{
Recursive(depth);
}
public void Recursive(int depth)
{
if (depth > 0)
System.Threading.Tasks.Parallel.Invoke(
delegate { Recursive(depth - 1); });
}
public void UpdateGui()
{
CalculateOhter(); // Works fine.
controlElement.Focus(); // Causes exception
}
编辑: 我知道Control.Invoke但这将是一个丑陋的解决方案(不想在每个控件中存储委托),程序需要等待所有计算完成才能继续。所以如果我能以某种方式强制控制返回到我最初开始的线程会更好。
答案 0 :(得分:1)
您需要从创建该控件的线程访问控件/窗口。使用Control.Invoke和Control.InvokeRequired。
答案 1 :(得分:0)
可怕的方法是将Control.CheckForIllegalCrossThreadCalls
设置为false。它应该摆脱你的错误,但这不是好设计。
当控件的创建线程以外的线程试图访问该控件的方法或属性之一时,会出现问题,这通常会导致不可预测的结果。
答案 2 :(得分:0)
Control.Invoke的示例涉及存储委托,这可以在不为每个控件存储委托的情况下完成吗?所以传递我需要调用的方法作为Invoke调用的参数(试过这个,但不能让它工作)。
程序需要等待所有计算完成才能继续,所以如果我能以某种方式强制控制返回到我最初开始的线程,那就更好了。
我不明白为什么在默认情况下不会发生这种情况,为什么它不只是在一切都完成后返回它开始的线程?
答案 3 :(得分:0)
解决了它,结果我创建了一个单独的线程来调用给定的代码,有点愚蠢:P