2

In dotNET with C# 4.0, How can I ensure that event that happens on an arbitrary thread X will call handlers in the same thread (or synchronization context) as the subscribing thread A, B, or C.

I am trying to avoid having to put in threading-related code into handler method or event site.

It would be really great if I wouldn't have to change += and -= subscription, as well as "public event EventHandler myevent;" code.

GregC
  • 7,737
  • 2
  • 53
  • 67

2 Answers2

1

I don't think you can directly do this. The best you can do is register handlers which will run on some arbitrary thread, but which will pass the data to the original thread.

Steven Sudit
  • 19,391
  • 1
  • 51
  • 53
  • It's the sort of thing I believe could make a programmer slightly more productive... oh just slightly. – GregC Sep 14 '10 at 02:51
  • Perhaps, but I'm not convinced it's particularly helpful. The one place it's useful is for dealing with GUI's, which need their controls modified only from the UI thread. However, both WinForms and WPF have solutions for this. Otherwise, it shouldn't matter which thread the event is executed in. – Steven Sudit Sep 14 '10 at 04:21
  • I actually have a continually-running orchestrator in a form of a complex state machine running in the background. I would like back-end logic and GUI to provide events that will drive the state machine. State machine runs on thread X, GUI on thread Y, and communications on thread Z. – GregC Sep 14 '10 at 05:12
  • No need to reinvent the wheel. Look at http://stackoverflow.com/questions/1203909/how-to-invoke-on-background-thread, http://stackoverflow.com/questions/670503/what-should-i-avoid-doing-on-background-thread-in-winforms, http://stackoverflow.com/questions/2526725/winforms-how-do-i-access-call-methods-in-ui-thread-from-a-separate-thread-witho – Steven Sudit Sep 14 '10 at 06:06
  • Ok, the only thing you need to worry about, other than the usual locking of shared resources, is updating controls from X or Z. To do that, use the `Control.Invoke` technique you'll find in the links above. These will ensure that your delegate is executed in Y, which has access to the message pump. – Steven Sudit Sep 14 '10 at 06:08
  • I am sure that with some reflection on this subject, you might note that it would be worthwhile to invest in providing a cleaner, crisper, and more direct user syntax. – GregC Sep 17 '10 at 23:04
  • 1
    Nope, I've reflected on it but I still disagree. Sorry. – Steven Sudit Sep 18 '10 at 01:02
  • Looks like C# design team agrees. Have a look as what's coming out in respect to async/await. – GregC Nov 17 '10 at 16:16
  • @GregC: Interesting. I was familiar with the feature, but it's nice to see a good use case for it. – Steven Sudit Nov 18 '10 at 18:05
0

This can currently be done with a TaskCompletionSource, combined with the default behavior of async/await that brings things back to the calling synchronization context.

GregC
  • 7,737
  • 2
  • 53
  • 67