[英]How to make a controlled infinite loop async in c#?
I found this 我找到了这个
Run async method regularly with specified interval 以指定的间隔定期运行异步方法
which does half of what I want, but at the same time I want to be able to stop the loop whenever I want and then resume it as well. 它完成了我想要的一半,但同时我希望能够在需要时停止循环,然后再恢复循环。 However while it's stopped, I don't want the infinite loop to keep running where the body gets skipped through a flag.
但是,当它停止时,我不希望无限循环在通过标志跳过主体的地方继续运行。
Basically I don't want this 基本上我不要这个
while (true) {
if (!paused) {
// run work
}
// task delay
}
because then the while loop still runs. 因为while循环仍然运行。
How can I set it so that while its paused, nothing executes? 如何设置它,使其在暂停时不执行任何操作?
How can I set it so that while its paused, nothing executes?
如何设置它,使其在暂停时不执行任何操作?
That's hard to answer: if you define "pause" as: the object state remains valid while the loop doesn't use any resources
then you'll have to stop and restart it (the loop). 很难回答:如果将“ pause”定义为:
the object state remains valid while the loop doesn't use any resources
则必须停止并重新启动它(循环)。
All other timers, including Thread.Sleep
, Task.Delay
s etc. will put your thread in idle/suspended mode. 所有其他计时器,包括
Thread.Sleep
, Task.Delay
等等,都将使您的线程处于空闲/暂停模式。
If that's not sufficient for your needs, you'll need to actually stop the "infinite" loop. 如果这还不足以满足您的需求,那么您实际上需要停止“无限”循环。
It will free up thread related resources as well. 它还将释放与线程相关的资源。
More info about sleep: 有关睡眠的更多信息:
You could use System.Threading.Timer
and dispose of it while it is not in use and re-create it when you are ready to "resume". 您可以使用
System.Threading.Timer
并在不使用它时进行处理,并在准备“恢复”时重新创建它。 These timers are light weight so creating and destroying them on demand is not a problem. 这些计时器重量轻,因此按需创建和销毁它们不是问题。
private System.Threading.Timer _timer;
public void StartResumeTimer()
{
if(_timer == null)
_timer = new System.Threading.Timer(async (e) => await DoWorkAsync(e), null, 0, 5000);
}
public void StopPauseTimer()
{
_timer?.Dispose();
_timer = null;
}
public async Task DoWorkAsync(object state)
{
await Task.Delay(500); // do some work here, Task.Delay is just something to make the code compile
}
If you are really adverse to timers and want it to look like a while loop, then you can use TaskCompletionSource<T>
: 如果您确实对计时器不利,并且希望它看起来像while循环,那么可以使用
TaskCompletionSource<T>
:
private TaskCompletionSource<bool> _paused = null;
public async Task DoWork()
{
while (true)
{
if (_paused != null)
{
await _paused.Task;
_paused = null;
}
//run work
await Task.Delay(100);
}
}
public void Pause()
{
_paused = _paused ?? new TaskCompletionSource<bool>();
}
public void UnPause()
{
_paused?.SetResult(true);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.