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# 非UI对象上的跨线程事件处理_C#_Multithreading - Fatal编程技术网

C# 非UI对象上的跨线程事件处理

C# 非UI对象上的跨线程事件处理,c#,multithreading,C#,Multithreading,我在处理与引发事件的线程不同的事件时遇到问题。但是,处理事件的对象不是UI对象,因此我不能使用Invoke执行委托并自动切换到UI线程进行事件处理 情况如下:我有一个包含多个表单的MDI应用程序。每个表单都有自己的控制器类,用于处理耦合表单和外部对象之间的通信。所有表格均为概览或详细表格(如ContactsOverview和ContactDetail),并共享相同的数据 在发生错误的情况下,表单以类似向导的顺序出现,比如说详细信息表单后面跟着概述表单。在详细信息表单中,以下概览表单上使用的数据发

我在处理与引发事件的线程不同的事件时遇到问题。但是,处理事件的对象不是UI对象,因此我不能使用Invoke执行委托并自动切换到UI线程进行事件处理

情况如下:我有一个包含多个表单的MDI应用程序。每个表单都有自己的控制器类,用于处理耦合表单和外部对象之间的通信。所有表格均为概览或详细表格(如ContactsOverview和ContactDetail),并共享相同的数据

在发生错误的情况下,表单以类似向导的顺序出现,比如说详细信息表单后面跟着概述表单。在详细信息表单中,以下概览表单上使用的数据发生了更改,在切换到概览表单之前,这些更改需要反映在该表单中。事件从细节表单引发,并由概览表单的控制器处理,概览表单对UI元素进行必要的更新

现在,在细节表单中保存更改的数据可能需要一段时间,因此UI必须保持响应性,并且应用程序的其他部分仍然可以使用。这就是为什么backgroundworker开始处理这个问题。保存数据时,在后台线程上引发事件。概览的控制器处理这个问题,但是当UI需要更新时,当然会出现跨线程异常

因此,我需要的是一种在UI线程上引发事件的方法,但由于处理不会发生在UI元素上,因此无法使用Invoke自动切换线程

通过在网上搜索,我找到了一个可能的解决方案,即使用生产者/消费者模式。但据我所知,这需要每个控制器在单独的线程中侦听事件队列。由于它是一个MDI应用程序,理论上可以有任意数量的带有控制器的表单,我不想启动那么多线程

欢迎提出任何建议。如果有一种方法可以避免同时使用backgroundworker,那么这也是一个合适的解决方案

谢谢你的阅读


Kevin

您可以在UI元素订阅的后台对象上拥有一个事件。在(订阅的)事件处理程序中(因此它是窗口代码的一部分),您可以访问调用。这就是我解决这个问题的方法。

您可以在UI元素订阅的后台对象上拥有一个事件。在(订阅的)事件处理程序中(因此它是窗口代码的一部分),您可以访问调用。这就是我解决这个问题的方法。

您可以使用,特别是,将消息发布到主同步上下文(这是GUI应用程序的主线程)

不幸的是,我对这个类及其用法了解不够,不能说这是一个确定的解决方案。特别是,如果不需要主线程来处理事件,而是需要一个特定的线程,我不知道应该怎么做

也许该类可以帮助您,它有一个公共的无参数构造函数,我想它可能会将它与当前线程关联,因此如果您从拥有控制器的线程构造该对象,并将其提供给后台线程代码,它可能会工作。

您可以使用,将消息发布到主同步上下文(GUI应用程序的主线程)

不幸的是,我对这个类及其用法了解不够,不能说这是一个确定的解决方案。特别是,如果不需要主线程来处理事件,而是需要一个特定的线程,我不知道应该怎么做

也许这个类可以帮助你,它有一个公共的无参数构造函数,我想它可能会将它与当前线程相关联,所以如果你从拥有控制器的线程构造这个对象,并将它交给后台线程代码,它可能会工作。

你可以试试这个,但我认为这不是最好的主意,只是一个临时工作

您还可以尝试在非图形线程中实例化发布对象,这可能会解决您的问题

还有一件事,你不能让你的UI组件句柄运行工作完成(使用间接方法)?

你可以试试这个,但我认为这不是最好的主意,只是一个解决办法

您还可以尝试在非图形线程中实例化发布对象,这可能会解决您的问题


还有一件事,你不能让你的UI组件句柄RunWorkerCompleted(使用间接寻址)吗?

问题是UI元素没有订阅事件,UI元素的控制器是,它只是一个普通的c类,没有调用方法。好吧。。。在这种情况下,我会说将控制器与UI元素完全解耦是不可行的,或者;)也许controlelr应该得到一个指向表单的指针,这样它就可以调用一些东西了……应用程序是在第三方框架上开发的,更改任何与UI和控制器之间的关系有关的内容都会导致代码大量更改。但是如果它像你建议的那样工作的话,它会为我们节省很多麻烦:)问题是UI元素没有订阅事件,UI元素的控制器是,它只是一个普通的c#类,没有调用方法。嗯。。。在这种情况下,我会说将控制器与UI元素完全解耦是不可行的,或者;)也许controlelr应该得到一个指向表单的指针,这样它就可以调用一些东西了……应用程序是在第三方框架上开发的,更改任何与UI和控制器之间的关系有关的内容都会导致代码大量更改。但是如果它像您建议的那样工作的话,它会为我们节省很多麻烦:)您的意思是从UI元素启动后台工作程序,然后通过RunWorkerComp中的UI元素访问UI线程