时间方法在另一个线程中执行,并在超时时中止



嗨,我试图异步运行方法以计时持续时间并在超过超时时取消该方法。

我试图使用 async 和 await 来实现这一点。但没有运气。也许我过度设计了这个,任何输入都将不胜感激

应该注意的是,我无法更改接口"他们的接口"(因此得名)

到目前为止的代码:

using System;
using System.Diagnostics;
public interface TheirInterface
{
    void DoHeavyWork();
}
public class Result
{
    public TimeSpan Elapsed { get; set; }
    public Exception Exception { get; set; }
    public Result(TimeSpan elapsed, Exception exception)
    {
        Elapsed = elapsed;
        Exception = exception;
    }
}
public class TaskTest
{
    public void Start(TheirInterface impl)
    {
        int timeout = 10000;
        // TODO
        // Run HeavyWorkTimer(impl)
        // 
        // Wait for timeout, will be > 0
        // 
        // if timeout occurs abortheavy
    }
    public Result HeavyWorkTimer(TheirInterface impl)
    {
        var watch = new Stopwatch();
        try
        {
            watch.Start();
            impl.DoHeavyWork();
            watch.Stop();
        }
        catch (Exception ex)
        {
            watch.Stop();
            return new Result(watch.Elapsed, ex);
        }
        return new Result(watch.Elapsed, null);
    }
}

您希望创建一个计时器,该计时器在过期时取消线程。如果没有合作取消,您将不得不致电Thread.Abort,这不太理想。我假设您知道中止线程所涉及的危险。

public Result HeavyWorkTimer(TheirInterface impl)
{
    var watch = new Stopwatch();
    Exception savedException = null;
    var workerThread = new Thread(() => 
    {
        try
        {
            watch.Start();
            impl.DoHeavyWork();
            watch.Stop();
        }
        catch (Exception ex)
        {
            watch.Stop();
            savedException = ex;
        }
    });
    // Create a timer to kill the worker thread after 5 seconds.
    var timeoutTimer = new System.Threading.Timer((s) =>
        {
            workerThread.Abort();
        }, null, TimeSpan.FromSeconds(5), TimeSpan.Infinite);
    workerThread.Start();
    workerThread.Join();
    return new Result(watch.Elapsed, savedException);
}

请注意,如果中止线程,线程将ThreadAbortException

如果您可以说服接口所有者添加协作取消,则可以更改计时器回调,以便它请求取消令牌而不是调用Thread.Abort

最新更新