简体   繁体   English

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

[英]Stop Task on long running method

I have an external dll with some methods I need to call. 我有一个需要调用某些方法的外部dll。 Also, I want to be able to configure a timeout for executing these methods, in order to abort them if execution time > config timeout. 另外,我希望能够配置执行这些方法的超时,以便在执行时间>配置超时时中止它们。 I call these methods on different tasks, like this: 我在不同的任务上调用这些方法,如下所示:

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

Now, I have the possibility to get the DynamicCall Thread id and abort it. 现在,我可以获取DynamicCall线程ID并中止它。 Is there any other way around? 还有其他办法吗? A more light way? 更轻松的方式? I can't use the Cancellation Tokes, since i can't modify the external Dll 我无法使用“取消通行卡”,因为我无法修改外部Dll

Thanks, Alex 谢谢,亚历克斯

Aborting a thread (especially a pool thread) is a really horrible thing to do. 中止线程(尤其是池线程)是一件非常可怕的事情 You may consider just letting each asyncFunction call come to an end naturally, without observing its result in case of time-out. 您可能会考虑让每个asyncFunction调用自然结束,而不观察超时的结果。 See "How do I cancel non-cancelable async operations?" 请参阅“如何取消不可取消的异步操作?”

On a side note, you're using Parallel.ForEach quite inefficiently here, the operation is taking roughly two times more threads than really needed. 附带一提,您在这里使用Parallel.ForEach效率很低,该操作占用的线程数大约比实际需要多两倍。 Without Parallel.ForEach , it might look like below, which is a better version, IMO: 如果没有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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM