长时间运行的方法停止任务

时间:2014-02-03 14:00:03

标签: c# .net multithreading timeout abort

我有一个外部dll,我需要调用一些方法。此外,我希望能够配置执行这些方法的超时,以便在执行时间> 1时中止它们。配置超时。 我将这些方法称为不同的任务,如下所示:

Parallel.ForEach(....
{
    Func<object> asyncFucntion = () => DynamicCall(method, paramList);
    IAsyncResult ar = asyncFucntion.BeginInvoke(null, null);
    if (ar.AsyncWaitHandle.WaitOne(timeout, true))
    {
        return asyncFucntion.EndInvoke(ar);
    }
    else
    {
        //HERE I NEED to stop DynamicCall. Timeout was EXCEEDED
    }
});

现在,我有可能获得DynamicCall线程ID并中止它。还有其他方法吗?更轻松的方式?我无法使用取消令牌,因为我无法修改外部Dll

谢谢, 亚历

1 个答案:

答案 0 :(得分:0)

中止线程(尤其是池线程)是really horrible thing要做的。您可以考虑让每个asyncFunction呼叫自然地结束,而不会在超时的情况下观察其结果。见"How do I cancel non-cancelable async operations?"

另一方面,你在这里使用Parallel.ForEach非常低效,操作所需的线程大约是实际需要的两倍。没有Parallel.ForEach,它可能如下所示,这是一个更好的版本,IMO:

var tasks = methods.Select(method =>
{
    Func<object> asyncFunction = () => DynamicCall(method, paramList);

    var task = Task.Factory.FromAsync(
        (asyncCallback, state) => asyncFunction.BeginInvoke(asyncCallback, state),
        (asyncResult) => asyncFunction.EndInvoke(asyncResult), 
        null);

    return Task.WhenAny(task, Task.Delay(timeout)).Unwrap();
});

Task.WhenAll(tasks).Wait(); // or Task.WaitAll();