我有一个简单的程序,输入一个数字并从0开始计数,我有1个计数器来做暂停和恢复(_nCurrentCount),下面的代码工作得很好,但是我取消了暂停任务对吗?有没有一种方法可以让你"暂停"一下?不取消该任务?
private void btnStart_Click(object sender, EventArgs e)
{
btnCancel.Enabled = true;
//Pause
if (tokenSource != null)
{
btnStart.Text = "RESUME";
tokenSource.Cancel();
tokenSource.Dispose();
tokenSource = null;
}
//Start and resume
else
{
tokenSource = new CancellationTokenSource();
btnStart.Text = "PAUSE";
countNumber(_nCurrentCount, tokenSource.Token).ContinueWith((t) =>
{
var _bPaused = false;
if (!Disposing && !IsDisposed && tokenSource != null)
tokenSource.Token.ThrowIfCancellationRequested();
if (InvokeRequired)
{
Invoke((MethodInvoker)(() =>
{
txtCount.Text = _nCurrentCount.ToString();
btnStart.Enabled = false;
}));
}
if (t.IsFaulted)
{
}
else if (t.IsCanceled)
{
_bPaused = true;
}
else
{
_bPaused = false;
_nCurrentCount = -1;
tokenSource.Dispose();
tokenSource = null;
btnStart.Text = "START";
}
}, TaskContinuationOptions.ExecuteSynchronously);
}
}
这是countNumber任务:
private async Task countNumber(int pnStart, CancellationToken pCancellationToken)
{
if (pnStart < 0)
pnStart = 0;
for (int i = pnStart; i <= Convert.ToInt32(txtInput.Text); i++)
{
pCancellationToken.ThrowIfCancellationRequested();
pnStart = i;
_nCurrentCount = i;
txtCount.Text = _nCurrentCount.ToString();
await Task.Delay(500);
}
}
以下是使用async
的版本:
private int _target = 0;
private int _counter = 0;
private CancellationTokenSource cts = null;
private async Task Execute(CancellationToken ct)
{
while (true)
{
txtCount.Text = $"{++_counter}";
if (_counter == _target)
{
btnStart.Text = "START";
break;
}
await Task.Delay(TimeSpan.FromMilliseconds(500.0));
if (ct.IsCancellationRequested)
{
break;
}
}
}
private async void btnStart_Click(object sender, EventArgs e)
{
if (_target == _counter)
{
if (int.TryParse(txtInput.Text, out int target) && target > 0)
{
_target = target;
_counter = 0;
txtCount.Text = $"{_counter}";
btnStart.Text = "PAUSE";
cts = new CancellationTokenSource();
await Execute(cts.Token);
}
else
{
txtCount.Text = "INVALID";
}
}
else
{
if (cts != null)
{
cts.Cancel();
cts = null;
btnStart.Text = "RESUME";
}
else
{
btnStart.Text = "PAUSE";
cts = new CancellationTokenSource();
await Execute(cts.Token);
}
}
}
private int _target = 0;
private int _counter = 0;
private async Task Execute()
{
while (true)
{
if (btnStart.Text == "PAUSE")
{
txtCount.Text = $"{++_counter}";
if (_counter == _target)
{
btnStart.Text = "START";
break;
}
}
await Task.Delay(TimeSpan.FromMilliseconds(500.0));
}
}
private async void btnStart_Click(object sender, EventArgs e)
{
if (btnStart.Text == "START")
{
if (int.TryParse(txtInput.Text, out int target) && target > 0)
{
_target = target;
_counter = 0;
txtCount.Text = $"{_counter}";
btnStart.Text = "PAUSE";
await Execute();
}
else
{
txtCount.Text = "INVALID";
}
}
else
{
btnStart.Text = btnStart.Text == "RESUME" ? "PAUSE" : "RESUME";
}
}