Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.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/2/.net/23.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#_.net_Multithreading_.net Core - Fatal编程技术网

C# 调用在另一个线程上运行的方法

C# 调用在另一个线程上运行的方法,c#,.net,multithreading,.net-core,C#,.net,Multithreading,.net Core,我正在从一个管理器类创建多个不同的线程。现在,当父应用程序中的变量发生更改时,我需要更新每个线程 所以我希望能够在线程中调用函数。最好的方法是什么?线程有一个对manager类的引用,所以我想从线程中轮询manager中的一个函数,以检查变量的更改,但这似乎不对,肯定有更好的方法。我查看了Dispatcher类,但这似乎也不对。有人能推荐最好的方法吗 account1 = new Account(this); account2 = new Account(this); T

我正在从一个管理器类创建多个不同的线程。现在,当父应用程序中的变量发生更改时,我需要更新每个线程

所以我希望能够在线程中调用函数。最好的方法是什么?线程有一个对manager类的引用,所以我想从线程中轮询manager中的一个函数,以检查变量的更改,但这似乎不对,肯定有更好的方法。我查看了Dispatcher类,但这似乎也不对。有人能推荐最好的方法吗

    account1 = new Account(this);
    account2 = new Account(this);
    Thread accountThread1 = new Thread(new ThreadStart(account1.Run));
    Thread accountThread2 = new Thread(new ThreadStart(account2.Run));

    accountThread1.Start();
    accountThread2.Start();

    // How do I call method on accountThread1 or 2?

如果我理解正确,您需要一种正确的方法来处理线程。 我不能给你正确的方法,但这是我处理线程的方法,可以从PLC 24/7获取数据而不会崩溃

样本如下:

//Create list of thread
    private List<Thread> threads = new List<Thread>();

    private void RunThread(YourClass yourclass)
    {
        switch (yourclass.ConnStat)
        {
            case ConnStatus.DISCONNECTED:
                {
                    Thread oldthread = threads.FirstOrDefault(i => i.Name == yourclass.ID.ToString());
                    if (oldthread != null)
                    {
                        //Clean old thread
                        threads.Remove(oldthread);
                    }
                    else
                    {
                        //Add event here
                        yourclass.OnResponseEvent += new EventHandler<YourClass.ResponseEventArgs>(work_OnResponseEvent);
                        yourclass.OnNotificationEvent += new EventHandler<YourClass.NotificationEventArgs>(work_OnInfoEvent);
                    }

                    try
                    {
                        //Add thread to list
                        Thread thread = new Thread(new ThreadStart(() => yourclass.Initialize())) { Name = yourclass.ID.ToString(), IsBackground = true };
                        thread.Start();
                        threads.Add(thread);
                        Thread.Sleep(100);
                    }
                    catch (ThreadStateException ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    break;
                }
            case ConnStatus.CONNECTED:
                {
                    MessageBox.Show(string.Format("ID:{0}, is currently running!", yourclass.ID));
                    break;
                }
            case ConnStatus.AWAITING:
                {
                    MessageBox.Show(string.Format("ID:{0}, is currently awaiting for connection!", yourclass.ID));
                    break;
                }
        }
    }

    //To control your class within thread
    private void StopThread(YourClass yourclass)
    {
        if (yourclass.ConnStat == ConnStatus.CONNECTED || yourclass.ConnStat == ConnStatus.AWAITING)
        {
            //Call your method
            yourclass.Disconnect();

            yourclass.OnResponseEvent -= work_OnResponseEvent;
            yourclass.OnDBResponseEvent -= work_OnDBResponseEvent;
            yourclass.OnNotificationEvent -= work_OnInfoEvent;

            Thread oldthread = threads.FirstOrDefault(i => i.Name == yourclass.ID.ToString());
            if (oldthread != null) threads.Remove(oldthread);
        }
    }
//创建线程列表
私有列表线程=新列表();
私有void RunThread(YourClass YourClass)
{
开关(yourclass.ConnStat)
{
案例ConnStatus.DISCONNECTED:
{
Thread oldthread=threads.FirstOrDefault(i=>i.Name==yourclass.ID.ToString());
if(oldthread!=null)
{
//清洁旧线
螺纹。移除(旧螺纹);
}
其他的
{
//在此处添加事件
yourclass.OnResponseEvent+=新事件处理程序(work\u OnResponseEvent);
yourclass.OnNotificationEvent+=新事件处理程序(work\u onInfo事件);
}
尝试
{
//将线程添加到列表中
Thread Thread=new Thread(new ThreadStart(()=>yourclass.Initialize()){Name=yourclass.ID.ToString(),IsBackground=true};
thread.Start();
线程。添加(线程);
睡眠(100);
}
捕获(ThreadStateException-ex)
{
MessageBox.Show(例如Message);
}
打破
}
case ConnStatus.CONNECTED:
{
Show(string.Format(“ID:{0},当前正在运行!”,yourclass.ID));
打破
}
正在等待的案件:
{
Show(string.Format(“ID:{0},当前正在等待连接!”,yourclass.ID));
打破
}
}
}
//在线程中控制类
私有void停止线程(YourClass YourClass)
{
如果(yourclass.ConnStat==ConnStatus.CONNECTED | | yourclass.ConnStat==ConnStatus.waiting)
{
//调用你的方法
yourclass.Disconnect();
yourclass.OnResponseEvent-=work\u OnResponseEvent;
yourclass.OnDBResponseEvent-=工作OnDBResponseEvent;
yourclass.OnNotificationEvent-=work\u oninfo事件;
Thread oldthread=threads.FirstOrDefault(i=>i.Name==yourclass.ID.ToString());
如果(oldthread!=null)线程。删除(oldthread);
}
}

希望这有助于

因此解决方案是使用一个有效的方法将变量更改推送到线程中,以获得所需的结果

使用观察者模式,所有正在运行的线程都可以在父应用程序中观察变量的变化。这样,线程不会轮询父线程,但线程可以响应主应用程序中变量的更改,从而有效地允许将更改的变量推送到所有线程中

MS文档链接有点复杂。我发现这是一个非常好的、易于遵循的教程:


使用生产者-消费者队列模式。没有对线程的调用-线程正在运行您的代码。不鼓励使用线程,特别是因为您可以使用整个TPL。遵循@DanielA.White的建议,熟悉
async
wait
Task
s@CamiloTerevinto每件事都有它的位置。@CamiloTerevinto如果某件事是cpu绑定的,那对线程/工作者来说更好,而不是异步代码。是的,我知道,但是,没有提供足够的信息来认为任务不适合这里。嗯,甚至没有足够的信息来回答