假设我有一个名为Tasking的组件(我无法修改),它暴露了一个方法"DoTask",它执行一些可能冗长的计算并通过事件TaskCompleted返回结果.通常,这是在用户在获得结果后关闭的窗体中调用的.
在我的特定场景中,我需要将一些数据(数据库记录)与TaskCompleted中返回的数据相关联,并使用它来更新数据库记录.
我已经调查了使用AutoResetEvent来处理事件的时间.问题是AutoResetEvent.WaitOne()将阻塞,永远不会调用事件处理程序.通常,AutoResetEvents被称为一个单独的线程,所以我想这意味着事件处理程序与调用的方法位于同一个线程上.
本质上我想通过阻塞将异步调用(通过事件返回结果)转换为同步调用(即从另一个类调用DoSyncTask),直到处理事件并将结果放在事件处理程序可访问的位置以及调用启动异步调用的方法的方法.
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; } }
我只需要在窗口服务中复制该行为,其中未调用Application.Run且ApplicationContext对象不可用.