在新线程c#windows应用程序中运行函数
我正在开发一个在窗口加载时调用函数populate()的应用程序 此函数的执行大约需要1分钟才能完成。我想让这个函数在单独的线程中调用 我正在使用以下代码在新线程c#windows应用程序中运行函数,c#,winforms,multithreading,C#,Winforms,Multithreading,我正在开发一个在窗口加载时调用函数populate()的应用程序 此函数的执行大约需要1分钟才能完成。我想让这个函数在单独的线程中调用 我正在使用以下代码 Thread thread = new Thread(PopulateAndDrawGraph); thread.Start(); 在这个函数中,最后一行是 nodeXlControl1.DrawGraph(true) 这里出现异常 调用线程无法访问此对象,因为其他线程拥有它 问题是,任何UI交互都必须发生在应用程序的主线程
Thread thread = new Thread(PopulateAndDrawGraph);
thread.Start();
在这个函数中,最后一行是
nodeXlControl1.DrawGraph(true)
这里出现异常
调用线程无法访问此对象,因为其他线程拥有它
问题是,任何UI交互都必须发生在应用程序的主线程中。我的建议是,在单独的线程中进行计算,但在对象中收集结果。线程完成后,您可以从该对象提取结果,并将其放置在NodeXlControl 1中 遗憾的是,我不知道你的目标的细节,解决方案的总和是这样的。
如果你能告诉我更多的细节,我可能会进一步帮助你。你只能从创建控件的同一线程中访问UI控件,通常是UI线程本身 您需要以线程感知的方式更改代码 下面是一篇发表在MSDN杂志上的精彩文章:,它将非常详细地解释如何做你想做的事情 这篇文章有点陈旧,但同样的原则仍然适用 我想较新的C语言功能——比如新的
async
/await
关键字——应该会让您的任务更简单一些
但请记住,访问UI控件的旧限制仍然存在。没有办法理解文章中描述的基础知识。请查看此处。它解释了有关跨线程调用的所有相关项目。我还建议您研究c#中“任务”的概念。有一个写得非常好的库,可以帮助您处理并行性和类似的概念 由于您试图从线程访问UI元素,因此需要调用
Invoke
。因此,在PopulateAndDrawGraph
中,您应该有:
Invoke((Action)(() =>
{
nodeXlControl1.DrawGraph(true);
}));
有两种处理方法,一种是正确的方法,另一种是: 1:如果你想要一个好的工作解决方案,那么这应该可以做到
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
msdn.microsoft.com/en-us/library/ms171728.aspx
2:但是如果您想要一个快速的解决方案而不保证它能正常工作,只需设置此变量:
除了创建此控件的线程外,您不能从任何其他线程访问UI控件(您只能从主UI线程访问/更改UI控件属性)。浏览此链接,我希望这能让您清楚我在c#中使用了BackgroundWorker类。您是否可以共享该异常的堆栈跟踪?仅链接的答案不是好答案。我知道您已链接到MSDN,但会发生更改,如果链接变差,此答案将变得无用。