如果我不再关心结果,有没有结束代表?

Joh*_*mis 5 c# multithreading delegates

我有一段代码可以搜索多个第三方API.我根据搜索条件将搜索分为两组.我开始两次搜索都是因为每次搜索都非常及时,但如果第一组搜索结果匹配,我不想等待第二个搜索组完成.基本上我所拥有的是:

Dictionary<string, string> result = null;
NameSearchDelegate nameDel = new NameSearchDelegate(SearchByName);
IAsyncResult nameTag = nameDel.BeginInvoke(name, null, null);
if(!string.IsNullOrWhiteSpace(telNum))
{
    result = SearchByTelNum(telNum);//Will return null if a match is not found
}
if(null == result)
{
    result = nameDel.EndInvoke(nameTag);
}
//End the delegate to prevent memory leak
//else
//{
//    nameDel.EndInvoke(nameTag)
//}
return result;
Run Code Online (Sandbox Code Playgroud)

所以我想在调用SearchByTelNum之前启动SearchByName,以防它找不到匹配项,但是如果找到匹配项我不想在返回匹配项之前等待SearchByName完成.如果我不再需要它的结果,有没有办法简单地结束或取消该委托?

Joh*_*mis 1

我能够使用 System.ComponentModel.BackgroundWorker 解决我的问题。我不一定按照预期的方式使用它,但它能够满足我的需要。所以我的新代码基本上是这样的:

Dictionary<string, string> telResult = null,
                           nameResult = null;

BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += (obj, e) => nameResult = SearchByName(name, bw);
bw.RunWorkerAsync();

if(!string.IsNullOrWhiteSpace(telNum))
    telResult = SearchByTelNum(telNum);//Will return null if a match is not found

if(telResult != null)
{
    bw.CancelAsync;
    return telResult;
}

bool hasTimedOut = false;
int i = timeOutCount;
while (bw.IsBusy && !hasTimedOut)
{
    System.Threading.Thread.Sleep(500);
    if (0 == --i) hasTimedOut = true;
}

return nameResult;
Run Code Online (Sandbox Code Playgroud)

为了确保没有错误,我必须确保 SearchByName 定期检查 bw.CancellationPending 是否等于 true,并在这种情况下结束该方法。CancelAsync 不会结束工作线程,它只是提醒工作线程调用者线程已取消它。

我也可以简单地使用

while(bw.IsBusy) System.Threading.Thread.Sleep(500)
Run Code Online (Sandbox Code Playgroud)

等待该方法完成,但如果 SearchByName 中发生问题,您可能会在无限循环中永远等待。通过这种方式,我可以在该方法被认为已超时之前设置一段时间,并且调用者线程将继续运行。在本例中,由于我每 0.5 秒检查一次 bw.IsBusy,因此超时长度等于 timeOutCount / 2 秒。

好吧,我想我已经彻底回答了我自己的问题。