让我们说我有一个工人阶级。
public sealed class Worker : IDisposable
{
private bool _isRunning;
private CancellationTokenSource _cts;
private readonly Action _action;
private readonly int _millisecondsDelay;
private readonly object _lock = new object();
public Worker(Action action, int millisecondsDelay)
{
_action = action;
_millisecondsDelay = millisecondsDelay = 5000;
}
public void Start()
{
lock (_lock)
{
if (!_isRunning)
{
_isRunning = true;
Run();
}
}
}
public void Cancel()
{
lock (_lock)
{
if (_isRunning) _cts.Cancel();
}
}
private void Run()
{
using (_cts) _cts = new CancellationTokenSource();
Task.Run(async () => { await DoAsync(_cts.Token); });
}
private async Task DoAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
//Log.Message1("____REFRESHING STATUS____");
_action();
await Task.Delay(_millisecondsDelay, cancellationToken);
}
//this code is unreachable
lock (_lock)
{
_isRunning = false;
}
}
public void Dispose()
{
try
{
_cts?.Cancel();
}
finally
{
if (_cts != null)
{
_cts.Dispose();
_cts = null;
}
}
}
}
问题是代码_isRunning = false;
无法访问。我的意思是,当调用方调用Cancel
方法时,工作人员将等待Task.Delay。因此,在取消任务后如何调用smth(此处为_isRunning = false;
)?换句话说,我需要确保我的工作程序没有运行(这不是取消状态)
答案 0 :(得分:3)
要回答字面上的问题,可以使用finally
块:
private async Task DoAsync(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
//Log.Message1("____REFRESHING STATUS____");
_action();
await Task.Delay(_millisecondsDelay, cancellationToken);
}
}
finally
{
lock (_lock)
{
_isRunning = false;
}
}
}
但是我对这种“工人”方法有些担忧:
Run
内部的“抛弃式”迷。我怀疑您会想要更改它。lock
与异步代码混合可能会出现问题。您应该绝对确定这是您真正想要做的。可能值得退后一步,重新考虑您实际上要使用此代码执行的操作。