Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在新线程c#windows应用程序中运行函数_C#_Winforms_Multithreading - Fatal编程技术网

在新线程c#windows应用程序中运行函数

在新线程c#windows应用程序中运行函数,c#,winforms,multithreading,C#,Winforms,Multithreading,我正在开发一个在窗口加载时调用函数populate()的应用程序 此函数的执行大约需要1分钟才能完成。我想让这个函数在单独的线程中调用 我正在使用以下代码 Thread thread = new Thread(PopulateAndDrawGraph); thread.Start(); 在这个函数中,最后一行是 nodeXlControl1.DrawGraph(true) 这里出现异常 调用线程无法访问此对象,因为其他线程拥有它 问题是,任何UI交互都必须发生在应用程序的主线程

我正在开发一个在窗口加载时调用函数populate()的应用程序

此函数的执行大约需要1分钟才能完成。我想让这个函数在单独的线程中调用

我正在使用以下代码

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,但会发生更改,如果链接变差,此答案将变得无用。