阻止代码并等待事件处理程序触发?

我正在编写一个使用第三方库来处理某些数据的应用程序。 在一个非常简单的例子中,我有一个像这样的任务运行的方法:

private void ProcessListOfItems(List items) { while (items.Count > 0) { 3rdPartyLibObject.Process(items[0]); items.Remove(0); } } 

正如您所看到的,我的代码当前编写的方式,我会在Process()方法返回后立即从列表中删除每个项目。 但是项目的处理可能会失败,我需要知道是否会发生这种情况。 不幸的是,Process()方法不返回bool值来指示项目是否已成功处理,而是会触发ProcessingComplete和ProcessingFailed事件。 我有事件处理程序连接到这样的事件:

 3rdPartyLibObject.ProcessingComplete += obj_ProcessingSuccess; 3rdPartyLibObject.ProcessingFailed += obj_ProcessingFailed; private void obj_ProcessingSuccess(object sender, 3rdPartyLibObject.ProcessingEventArgs e) { this.Invoke(new ProcessedHandler(OnProcessed), new object[] { true }); } private void obj_ProcessingFailed(object sender, 3rdPartyLibObject.ProcessingEventArgs e) { this.Invoke(new ProcessedHandler(OnProcessed), new object[] { false }); } private void OnProcessed(bool success) { if (success) { Debug.WriteLine("Item was processed succesfully!"); } else { Debug.WriteLine("Failed to process item!"); } } 

我想要做的是在调用3rdPartyLibObject.Process()之后立即使用我的代码块,直到其中一个事件处理程序触发,因此我知道该项是否无法处理(以及我是否应将其从列表与否)。 我猜这可能不是一个不常见的情况,但我以前从未遇到过这种情况。 是否有一个普遍认同的最佳做法来处理这种情况?

就个人而言,我会把它包装成一个Task ,就像这样:

 Task Process3rdParty(ThirdPartyLibObject thirdParty, string item) { var tcs = new TaskCompletionSource(); thirdParty.ProcessingComplete += (o, e) => tcs.SetResult(true); thirdParty.ProcessingFailed += (o, e) => tcs.SetResult(false); thirdParty.Process(item); return tcs.Task; } 

你可以这样调用它:

 private void ProcessListOfItems(List items) { while (items.Count > 0) { var task = Process3rdParty(thirdPartyLibObject.Process(items[0]); if (task.Result) items.Remove(0); } } 

如果您稍后决定要异步运行或一次处理多个项目(如果第三方库支持此项),这也会简化操作。 这也很容易转移到C#5的异步/等待支持,以使整个事件异步。

这会工作:

 private bool itemProcessed = false; private void ProcessListOfItems(List items) { while (items.Count > 0) { 3rdPartyLibObject.Process(items[0]); if (itemProcessed) { items.Remove(0); } } } private void obj_ProcessingSuccess(object sender, 3rdPartyLibObject.ProcessingEventArgs e) { this.itemProcessed = true; } private void obj_ProcessingFailed(object sender, 3rdPartyLibObject.ProcessingEventArgs e) { this.itemProcessed = false; } 

假设事件在同一个线程上全部触发,则应在处理下一个项目之前调用处理程序。