考虑一个带有2个按钮和富文本框的表单:
任务声明完成后(在上面的代码中),编译完全没有问题,并且可以无误运行。
编辑:
如果
另外,稍微不相关的是,我在这里正确地处理了
第二次编辑:
所以,这是正确的方式吗:
并且
public partial class MainForm : Form
{
CancellationTokenSource cts;
CancellationToken token;
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
token = cts.Token;
var task = Task.Run(() => WriteSomeLines(), token);
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
cts.Dispose();
}
private void btnStart_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
token = cts.Token;
var task = Task.Run(() => WriteSomeLines(), token);
}
private void btnCancel_Click(object sender, EventArgs e)
{
try
{
cts.Cancel();
cts.Dispose();
}
catch (ObjectDisposedException exc)
{
MessageBox.Show(exc.GetType().Name);
//object disposed
}
}
public void WriteSomeLines()
{
if (ControlInvokeRequired(rtbLoops, () => rtbLoops.Text += "Starting new loop \r\n")) ;
else rtbLoops.Text += "Starting new loop \r\n";
for (int i = 0; i < 30; i++)
{
try
{
if (ControlInvokeRequired(rtbLoops, () => { rtbLoops.AppendText("New line " + i + "\r\n"); rtbLoops.ScrollToCaret(); })) ;
else rtbLoops.AppendText("New line " + i + "\r\n");
Thread.Sleep(250);
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException ae)
{
MessageBox.Show(ae.GetType().Name);
return;
}
}
return;
}
public bool ControlInvokeRequired(Control c, Action a)
{
if (c.InvokeRequired)
c.Invoke(new MethodInvoker(delegate { a(); }));
else
return false;
return true;
}
}
< p >如果 < code >WriteSomeLines() 返回的是 void 类型并且我在其中使用了 return 语句,或者 < code >WriteSomeLines() 返回的是 Task 类型并且我在其中使用了 return null 语句,这两种情况有什么区别吗?我读到过不能使用 await 关键字来等待返回 void 的方法,但是插入…< /p >
await task;
任务声明完成后(在上面的代码中),编译完全没有问题,并且可以无误运行。
编辑:
private async void btnStart_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
token = cts.Token;
var task = Task.Run(() => WriteSomeLines(), token);
await task;
rtbLoops.Text += "Task complete";
}
如果
WriteSomeLines()
返回 void,那么这个可以顺利编译。另外,稍微不相关的是,我在这里正确地处理了
CancellationTokenSource
吗?第二次编辑:
所以,这是正确的方式吗:
private async void btnStart_Click(object sender, EventArgs e)
{
cts.Dispose();
cts = new CancellationTokenSource();
token = cts.Token;
var task = Task.Run(() => WriteSomeLines(), token);
bool result = await task;
if(result == true) rtbLoops.Text += "Task complete \r\n";
}
并且
public async Task<bool> WriteSomeLines()
{
if (ControlInvokeRequired(rtbLoops, () => rtbLoops.Text += "Starting new loop \r\n")) ;
else rtbLoops.Text += "Starting new loop \r\n";
for (int i = 0; i < 30; i++)
{
try
{
if (ControlInvokeRequired(rtbLoops, () => { rtbLoops.AppendText("New line " + i + "\r\n"); rtbLoops.ScrollToCaret(); })) ;
else rtbLoops.AppendText("New line " + i + "\r\n");
await Task.Delay(250);
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException ae)
{
MessageBox.Show(ae.GetType().Name);
return false;
}
}
return true;