【发布时间】:2014-06-24 09:14:42
【问题描述】:
我将一些代码从一个 winforms 控件对象移动到一个单独的对象以实现更好的模块化。但是,有一些对发出回调的外部对象的调用,我无法控制这些调用,并且可以作为主 UI 线程从不同的线程中触发。为了避免这种情况,我使用众所周知的 BeginInvoke 方案来检查是否应该将调用转移到主 UI 线程。
当我现在将此代码移动到我的分离对象时,我不再需要 Winforms 引用。我可以处理一个 Control 对象,以确保一切都在同一个线程中运行。但我宁愿有一个通用机制,它的作用与确保 Threadconext 完全相同,例如创建对象或调用特定入口函数也用于随后发出的调用,例如通过外部回调。
这如何最容易实现?
例子:
public class Example
{
ThreadedComponent _Cmp = new ThreadedComponent();
public Example()
{
_Cmp.ThreadedCallback += new ThreadedComponent.CB(Callback);
}
public void StartFunction()
{
// called in ThreadContextA
_Cmp.Start();
}
void Callback(Status s)
{
// is called in ThreadContextB
if(s == SomeStatus)
_Cmp.ContinueFunction(); // must be called in ThreadContextA
}
}
澄清
ContinueFunction 必须从调用 StartFunction 的同一个 ThreadContext 调用。这不一定是 UI 线程,但目前它当然是按钮处理程序。
【问题讨论】:
-
您的单独组件可能不应该引用 UI。所以它不应该知道必须以同步方式访问 UI 的事实。只要它知道 UI 存在,它就不会真正分离。
-
在你的外部组件和 UI 之间放置一些东西。委托、事件或接口。然后这个中间人可以在外部组件不知道的情况下与 UI 同步。
-
@usr:正如我在第一个答案下方的评论中所写,我想我正在使用自己的线程事件队列,然后在定义的上下文中执行任务。
-
您不需要任何消息队列。你只需要在你的组件和
Control.Invoke之间有一个很小的层,这样你的组件甚至不需要知道有控件这样的东西。发布一些代码,我可以看看这种模式是否适用于您的情况。 -
将UI同步逻辑添加到
Callback。ThreadedComponent不需要知道。
标签: c# .net multithreading thread-safety