我需要一个在线程和事件提升方面具有高技能的人。
我有一个抽象类A
和两个具体类C1
,C2
(例如插件)。
由于我需要它们彼此之间进行通信,比如“插件 - 应用程序”“插件 - 插件”通信,我在抽象类中有一个方法ExecuteCommand
,它应该实现这一点。此函数向应用程序引发event
以处理某个命令并返回结果(例如,如果一个插件需要来自应用程序的数据,它从基础调用ExecuteCommand
并等待结果在应用程序上处理事件处理程序。)
protected object ExecuteCommand(SvcCmdType cmdType, params object[] inputParams)
{
// this code has been simplified
SvcCommandEventArgs eventArgs = new SvcCommandEventArgs(cmdType, inputParams);
// generate processing command event (it requires to fill in the result)
OnProcessingAppCommand(this, eventArgs);
return eventArgs.OutputParamsList;
}
问题 是:
如果C1
和C2
中的每一个都有不同的线程,并且同时从他们自己的线程中调用ExecuteCommand
那么肯定我的设计将被破坏并且返回的结果将是意外的
这种情况的最佳设计是什么?我在考虑使用ExecuteCommand
内部AsyncOperation
异步调用,但这是正确的方法吗?
编辑: 我想我正在寻找:同步或异步方式更适合我的场景吗?或者,我是否应该在插件的线程内处理应用程序事件处理程序或在我的主线程中的某处同步?
我非常感谢您对推荐的一些好解释
谢谢。
答案 0 :(得分:1)
在公共资源或代码块上执行线程同步的常用简单方法是使用互斥锁(或者,在本例中为临界区)。使用lock语句:
http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx
本文说要对“this”指针进行锁定,但这可能很危险,因为外部调用者也可能获得相同的锁定,这可能会破坏您的程序。锁定私有类变量。
以下是对示例代码进行的一些修改,以包含锁定/关键部分:
class SomeClass : ISomeInterface
{
protected object ExecuteCommand(SvcCmdType cmdType, params object[] inputParams)
{
lock(executeCommandLock)
{
SvcCommandEventArgs eventArgs = new SvcCommandEventArgs(cmdType, inputParams);
OnProcessingAppCommand(this, eventArgs);
return eventArgs.OutputParamsList;
}
}
private Object executeCommandLock = new Object();
}
修改强>
(从评论中解释)。您提到过,您可能希望异步处理单个线程上对ExecuteCommand的所有调用。您可以使用Dispatcher类完成此操作:
http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx
在一个线程上获取对调度程序的引用。将该引用传递给其他线程。当这些线程想要调用ExecuteCommand时,它们使用dispatcher.BeginInvoke。由于它们使用BeginInvoke,因此对ExecuteCommand的所有调用都将异步操作,而不是在该线程上阻塞。但是,每个版本的ExecuteCommand都将排队,并按顺序运行调度程序线程。