简体   繁体   English

在具有超时的同一线程(无线程池)中同步运行任务

[英]Synchronously run a task in the same thread (no threadpool) with a timeout

I want to use Task<> type, but not with TPL, but with .NET4.5/C#async instead. 我想使用Task <>类型,但不是使用TPL,而是使用.NET4.5 / C#async。

Thing is, I have some requirements for my case: 事实是,我对我的案子有一些要求:

  • I want the task to be run synchronously (some people recommend RunSynchronously() , others Wait() , and others ContinueWith(_, TaskContinuationOptions.ExecuteSynchronously) , which one is the adequate here?). 我希望任务同步运行(有些人推荐RunSynchronously() ,其他人Wait() ,还有其他的ContinueWith(_, TaskContinuationOptions.ExecuteSynchronously) ,哪一个就足够了?)。
  • I want the task to run in the same thread (so, not use the threadpool at all). 我希望任务在同一个线程中运行(所以,根本不使用线程池)。
  • I want the task to stop after a certain timeout has passed, and throw an exception. 我希望任务在超过某个超时后停止,并抛出异常。

For the latter, I think I need Task.Delay() but I'm not sure how to combine it with the first two requirements. 对于后者,我认为我需要Task.Delay()但我不确定如何将它与前两个要求结合起来。 Thanks 谢谢

This answer is based on @svick's comment. 这个答案是基于@ svick的评论。

I'm going to make the assumption that you want all the "work" of the method to be done on the same thread as the caller, but that you don't mind if a thread pool thread is used for cancellation purposes (I'm assuming this since you mentioned Task.Delay which will use a Timer which will use a thread pool thread when the timer fires. 我将假设您希望方法的所有“工作”都在与调用者相同的线程上完成,但是您不介意线程池线程是否用于取消目的(I'假设这是因为你提到了Task.Delay ,它将使用一个Timer ,当计时器触发时它将使用一个线程池线程。

That said, there would be no need for Task , since when the method returns you would know for certain that the Task was completed. 也就是说,不需要Task ,因为当方法返回时,您肯定知道任务已完成。 Just a regular method with a timeout will do: 只是一个超时的常规方法会:

static void DoSomethingOrThrowAfterTimeout(int millisecondsTimeout)
{
    CancellationTokenSource cts = new CancellationTokenSource(millisecondsTimeout);
    CancellationToken ct = cts.Token;
    // do some work
    ct.ThrowIfCancellationRequested();
    // do more work
    ct.ThrowIfCancellationRequested();
    // repeat until done.
}

Obviously, with this approach of using cooperative cancellation, the method won't timeout exactly at the timeout, as it will be dependent on how small you can split up the work in the method. 显然,使用这种使用协作取消的方法,该方法不会在超时时准确超时,因为它取决于您在方法中拆分工作的程度。

If you want to avoid the usage of another thread (for the CancellationTokenSource ), then you could track the starting time and then check how much time has passed (to see if you've exceeded the timeout) at various points in the method (like how ct.ThrowIfCancellationRequested() is used above. 如果你想避免使用另一个线程(对于CancellationTokenSource ),那么你可以跟踪开始时间,然后在方法的不同点检查已经过了多少时间(看你是否超过了超时)(比如如何在上面使用ct.ThrowIfCancellationRequested()

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

相关问题 在没有ThreadPool的wpf(c#)应用程序中一次又一次地重复使用同一单线程执行同一任务 - Reuse same single thread for same task again and again in wpf (c#) application without ThreadPool Task.Run(Action)是否启动新的线程ID,所以ThreadPool中没有更多线程了吗? - Does Task.Run(Action) Start a new Thread id there are no more threads in the ThreadPool? 新的Task总是在ThreadPool线程上执行吗? - Is new Task always executed on ThreadPool thread? 如何保证Task在当前线程上同步运行? - How to guarantee that a Task runs synchronously on the current thread? 在UI线程上同步取消待处理的任务 - Cancelling a pending task synchronously on the UI thread 在.NET 4中,BeginInvoke和Task是否使用相同的线程池? - In .NET 4, does BeginInvoke and Task use the same threadpool? Xamarin iOS运行任务,同步返回值 - Xamarin iOS Run Task with return value synchronously 使TaskScheduler同步并在主线程中运行 - Make the TaskScheduler synchronously and run in the main thread 同步等待异步方法在同一线程上完成 - Wait synchronously for an async method to finish on the same thread 线程池还使用阻塞的线程从队列中执行新任务吗? - Threadpool also uses a blocked thread to execute a new task from queue?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM