分组码,并等待事件处理程序来火?(Block code and wait for event han

2019-08-01 12:08发布

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

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

正如你所看到的,我的代码,目前正在编写方式,我从列表中尽快删除每个项目的工艺路线()方法返回。 但是,它可能是一个项目的处理可能会失败,我需要知道,如果发生这种情况。 不幸的是,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(后右),直至事件处理程序的火灾之一,所以我知道,如果该项目未能处理或没有(我是否应该将其删除列出与否)。 我猜测,这可能不是一个罕见的情况,但我以前从来没有碰到这个问题。 有没有在最佳实践来处理这种情况的普遍认同?

Answer 1:

就个人而言,我将包装这个成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的异步/等待支持,使整个事情异步。



Answer 2:

将这项工作:

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;
}

假设事件在同一线程上的所有火,你处理下一个项目之前的处理程序被调用。



文章来源: Block code and wait for event handler to fire?