嗨,我试图异步运行方法以计时持续时间并在超过超时时取消该方法。
我试图使用 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
。