Note that there are some explanatory texts on larger screens.

plurals
  1. POIs it possible to put an event handler on a different thread to the caller?
    text
    copied!<p>Lets say I have a component called Tasking (that I cannot modify) which exposes a method “DoTask” that does some possibly lengthy calculations and returns the result in via an event TaskCompleted. Normally this is called in a windows form that the user closes after she gets the results.</p> <p>In my particular scenario I need to associate some data (a database record) with the data returned in TaskCompleted and use that to update the database record.</p> <p>I’ve investigated the use of AutoResetEvent to notify when the event is handled. The problem with that is AutoResetEvent.WaitOne() will block and the event handler will never get called. Normally AutoResetEvents is called be a separate thread, so I guess that means that the event handler is on the same thread as the method that calls. </p> <p>Essentially I want to turn an asynchronous call, where the results are returned via an event, into a synchronous call (ie call DoSyncTask from another class) by blocking until the event is handled and the results placed in a location accessible to both the event handler and the method that called the method that started the async call.</p> <pre><code>public class SyncTask { TaskCompletedEventArgs data; AutoResetEvent taskDone; public SyncTask() { taskDone = new AutoResetEvent(false); } public string DoSyncTask(int latitude, int longitude) { Task t = new Task(); t.Completed = new TaskCompletedEventHandler(TaskCompleted); t.DoTask(latitude, longitude); taskDone.WaitOne(); // but something more like Application.DoEvents(); in WinForms. taskDone.Reset(); return data.Street; } private void TaskCompleted(object sender, TaskCompletedEventArgs e) { data = e; taskDone.Set(); //or some other mechanism to signal to DoSyncTask that the work is complete. } } In a Windows App the following works correctly. public class SyncTask { TaskCompletedEventArgs data; public SyncTask() { taskDone = new AutoResetEvent(false); } public string DoSyncTask(int latitude, int longitude) { Task t = new Task(); t.Completed = new TaskCompletedEventHandler(TaskCompleted); t.DoTask(latitude, longitude); while (data == null) Application.DoEvents(); return data.Street; } private void TaskCompleted(object sender, TaskCompletedEventArgs e) { data = e; } } </code></pre> <p>I just need to replicate that behaviour in a window service, where Application.Run isn’t called and the ApplicationContext object isn’t available.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload