Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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#中的多个线程中更新多个表单?_C#_Multithreading_Winforms - Fatal编程技术网

如何在c#中的多个线程中更新多个表单?

如何在c#中的多个线程中更新多个表单?,c#,multithreading,winforms,C#,Multithreading,Winforms,我遇到了一个自己似乎无法解决的问题。我的程序是另一个应用程序的覆盖。它在不同的线程中运行多个windows窗体。他们都独立完成所有工作,但我需要不时地更新这些表单中的数据(具体的标签)。每个表单的数据都是唯一的,所以我不能同时更新所有的数据 到目前为止,我最好的线索是,和。但是,它们都不能处理跟踪窗口类的多个实例的问题。这就是我需要帮助的地方 现在代码如下所示: > public class main { > > //This is the class,

我遇到了一个自己似乎无法解决的问题。我的程序是另一个应用程序的覆盖。它在不同的线程中运行多个windows窗体。他们都独立完成所有工作,但我需要不时地更新这些表单中的数据(具体的标签)。每个表单的数据都是唯一的,所以我不能同时更新所有的数据

到目前为止,我最好的线索是,和。但是,它们都不能处理跟踪窗口类的多个实例的问题。这就是我需要帮助的地方

现在代码如下所示:

    > public class main {
    >
    > //This is the class, that organizes all the forms
    > //and creates or updates them if needed. The forms are being created like this: 
    >
    > new Thread(() => new Overlay(neededDataByOverlay).ShowDialog()).Start();
    >
    > }
    >
    > public class Overlay {
    >
    > //This is the overlay which I need to update from time to time. 
    > //Ideally I would like to call a method update(dataThatNeedsToBeUpdated) so it can update itself. 
    > //There will be multiple instances of this class at the same time.
    > 
    > }
我的问题是,如何跟踪不同线程中的不同形式,然后在其中调用该方法? 是否可以创建一个包含线程的列表,或者我是否可以以某种方式将正在运行的表单放入列表中?我需要通过名称或其他方式标识每个窗口,以便将正确的数据发送到正确的窗口。我真的被这件事缠住了,如果能得到任何帮助,我将不胜感激

编辑:显然不清楚我对这个程序的意图是什么,以及为什么表单需要在单独的线程中。这些表格是股票交易程序的叠加。它们根据使用的程序或当前打开的窗口显示附加信息。 例如,股票交易程序的一个窗口显示了货币汇率,因此叠加显示了与货币相关的其他信息,而股票交易程序不会开箱即用。然后,另一个窗口实时显示股票价格,覆盖图在顶部显示其他信息

覆盖层(表单)根据底层窗口的位置不断调整大小和调整自己(实际上正在进行一些计算),这就是为什么它们需要在自己的线程中。否则,窗体的大小调整计时器和计算方法将阻塞主线程。只要有新的数据集可用,我的应用程序的主类就会从特定的服务器获取数据。因此,例如:一旦新的货币汇率数据集可用,它就会得到处理,并且需要更新特定的覆盖

现在,跟踪所有表单(例如form1.purpose=currency,form2.purpose=stocks)并在其线程中使用我的主线程在设置的时间间隔内获取的新数据集更新它们的最佳方法是什么


非常抱歉,如果这不能回答您的问题,我会尽力解释这个问题。

您可以创建一个对象并将其作为参数传递给线程。
执行此操作时,对象通过引用传递 这意味着所做的任何更改都会反映在源对象上。

无论是对是错,要做您想做的事情,您可以将对象的引用传递给创建的线程,然后
ShowDialog
从那里的线程中获取表单。
以下是一个例子:

Form1 myForm = new Form1();
Thread t = new Thread((formObj) =>
{
    (formObj as Form1).ShowDialog();
});
t.Start(myForm);


//Testing the "making-changes-to-the-form-part"
DataGridView dgv = new DataGridView();
dgv.Dock = DockStyle.Fill;
if (myForm.InvokeRequired)
    myForm.BeginInvoke(new Action(() => { myForm.Controls.Add(dgv); }));
else
    myForm.Controls.Add(dgv);
但是,这里需要考虑以下几点:
窗体的对象是在主线程上创建的,而窗口句柄是在子线程中创建的,这就是为什么窗体窗口的所有者是子线程。

注意if(myForm.invokererequired)的用法,在本例中是正确的。。这会导致应用程序启动控件,并调用其所有者线程对其ui进行更改。

我不清楚你申请的目的,而且你所做工作的性质似乎有问题,我所知甚少。
但问题是,一旦子线程使用了forms实例,您如何访问它。。。我想?你就是这样做的。

因此,为了能够访问一个表单的多个实例,您需要这些表单的集合可能与使用集合(如
Dictionary
)和上面的代码的标识符配对

但是
看到您的eddited问题后,我开始想知道为什么您不使用
System.Windows.Forms.Timer
而不是调用main form的方法

以下是一个例子:

这样,当您显示计时器时,您的窗体将初始化计时器,并且该计时器将在计时器上调用该方法,这对您来说麻烦更少,并且您不必以这种方式进行跨线程调用。

也。。。既然您谈到线程安全列表,我建议您阅读。
它提供了很多关于多线程和线程安全的信息。

我对您真正想要做的事情有点困惑。您创建的线程仅以模态方式显示对话框。为什么?当然可以将表单对象放入列表中,但为什么?线程已经知道它们的形式,如果它们是独立的,那么问题是什么?通常,从UI线程以外的任何其他线程对UI执行任何操作都是一件坏事,因此我认为设计可能有问题。您是否尝试过将表单作为主线程的参数传递给线程?还是不明白你的问题出在哪里。。。你想从主线程更新其他线程中表单的ui吗?@SamiKuhmonen请参阅我的编辑以获得更全面的解释。我希望我能更好地概括我的问题。谢谢你的帮助@Niklas我还没试过。我该怎么做呢?是的,这正是我想要做的!BackgroundWorker和Timer可能是一个比手动运行多个线程更好的解决方案,尤其是在UI上。感谢您迄今为止的帮助!我编辑了我的问题,因此更容易理解应用程序的目的。你的回答有道理。其思想是在主线程中创建对象,然后使用.ShowDialog()将其传递给线程,这样我们以后仍然可以访问它的方法(尽管调用比只调用方法要复杂一些),对吗?但我不太明白第二部分。为什么选择DataGridView?有多个实例的部分听起来也不错!我得埋头工作
private Timer _timer;
private void Form1_Load(object sender, EventArgs e)
{
    if (_timer == null)
    {
        _timer = new Timer
        {
            Interval = (int)TimeSpan.FromSeconds(10).TotalMilliseconds
        };
        _timer.Tick += (s, args) =>
        {
            //Method calls of the form itself here
        };
        _timer.Start();
    }
}