阻止代码并等待事件处理程序启动



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

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

正如您所看到的,按照当前编写代码的方式,一旦Process()方法返回,我就会从列表中删除每个项。但项目的处理可能会失败,我需要知道是否会发生这种情况。不幸的是,Process()方法不会返回布尔值来指示该项是否已成功处理,而是会触发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<bool>中,如下所示:

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

然后你可以这样称呼它:

private void ProcessListOfItems(List<string> 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<string> 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;
}

假设事件都在同一个线程上激发,那么在处理下一个项目之前应该调用处理程序。

相关内容

  • 没有找到相关文章

最新更新