C# multiple sources, different threads, one event handler

坚强是说给别人听的谎言 提交于 2019-12-22 10:31:04

问题


I need somebody with high skills in threading and event raising.

I have an abstract class A and two concrete classes C1, C2 (e.g plugins).

Since I need them to communicate between each other, like "plugin-application" "plugin-plugin" communication, I have a method ExecuteCommand in the abstract class which should accomplish this. This function raises an event to the application in order to process a certain command and return the result (e.g if one plugin needs data from the app it calls ExecuteCommand from the base and waits for the result which comes with the event handler processed on the application).

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; 
}

The problem is:

If each one of C1 and C2 have different threads behind and call simultaneously ExecuteCommand from inside their own threads then for sure my design will be broken and the result returned will be unexpected.

What is the best design for this scenario? I was thinking to use inside ExecuteCommand asynchronous calls like using AsyncOperation... but is it the right way?

edited: I guess I am looking for: is the synchronous or asynchronous way better for my scenario? Or, shall I have the app event handler processed inside a plugin's thread or synchronized somewhere in my main thread?

I would really appreciate some good explanations for your recommendations

Thank you.


回答1:


The usual simple method of doing thread synchronization on a common resource or code block is to use a mutex (or, in this case, a critical section). Use the lock statement:

http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx

This article says to do locking on the "this" pointer, but that can be dangerous, as outside callers could also acquire the same lock, which could break your program. Do your locking on a private class variable.

Here is some modification of your example code to incorporate locking/a critical section:

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();
}

Edit:

(paraphrasing from comments). You mentioned that you might want to process all calls to ExecuteCommand on a single thread, asynchronously. You may be able to accomplish this with the Dispatcher class:

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx

Get a reference to the dispatcher on one thread. Pass that reference to the other threads. When those threads want to call ExecuteCommand, they use dispatcher.BeginInvoke. Since they use BeginInvoke, all calls to ExecuteCommand will then operate asynchronously, and not block on that thread. However, each version of ExecuteCommand will be queued up, and run sequentially dispatcher thread.



来源:https://stackoverflow.com/questions/3447189/c-sharp-multiple-sources-different-threads-one-event-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!