C# 在另一个线程中计时方法执行,并在超时时中止
嗨,我正在尝试运行一个异步方法,以便对持续时间计时,并在超过超时时取消该方法 我试着用async和Wait来实现这一点。但是没有运气。也许我在这方面做得太过火了,任何意见都将受到赞赏 需要注意的是,我无法更改接口“TheirInterface”(因此得名) 迄今为止的代码:C# 在另一个线程中计时方法执行,并在超时时中止,c#,multithreading,task-parallel-library,C#,Multithreading,Task Parallel Library,嗨,我正在尝试运行一个异步方法,以便对持续时间计时,并在超过超时时取消该方法 我试着用async和Wait来实现这一点。但是没有运气。也许我在这方面做得太过火了,任何意见都将受到赞赏 需要注意的是,我无法更改接口“TheirInterface”(因此得名) 迄今为止的代码: using System; using System.Diagnostics; public interface TheirInterface { void DoHeavyWork(); } public cla
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);
}
}
您想创建一个计时器,当它过期时,将取消线程。如果没有合作取消,您将不得不调用
线程.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
如果您能说服接口所有者添加合作取消,然后,您可以更改计时器回调,使其请求取消令牌,而不是调用
线程。Abort
您可能应该通过要求取消令牌
作为接口.DoHeavyWork
中的参数来强制执行协同取消,并将其转到任务
。。。否则,据我所知,没有干净的方法“中止”在同一进程中运行的其他操作。@PatrykĆwiek很好的调用,我将向接口所有者建议。@PatrykĆwiek有最好的解决方案。你的其他选择是:启动一个专用线程并在超时时中止它(这会破坏应用程序域的稳定性);启动一个专用的应用程序域,并在超时时卸载它(这可能会破坏进程的稳定性);启动一个单独的进程,并在超时时终止它(这是中止不可取消代码的唯一真正安全的方法)。@StephenCleary我不同意这是解决方案。它没有解决超时要求,它只解决了优雅的中止-所以从我的角度来看,这个问题仍然存在stands@LarsNielsen好的,如果接口接受CancellationToken
并异步工作,您可以取消一个。感谢您的输入,不幸的是接口所有者不想支持取消。我不敢中断这条线索,因为我不知道后果如何。因此,我没有调用workerThread.Abort(),而是决定引发一个事件,发出超时信号并通知用户。