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

时间:2013-12-18 14:08:44

标签: c# multithreading task-parallel-library

您好我正在尝试运行方法异步以便为持续时间计时并在超出超时时取消该方法。

我试过使用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);
    }
}

1 个答案:

答案 0 :(得分:0)

您想要创建一个计时器,当计时器到期时取消该计划。如果没有合作取消,您必须致电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