C#控件回调事件中使用异步操作的方法
注意点
async、await 关键字一般成对出现,表示是异步函数。
async 里的代码可能在主线程运行,也可能在新线程运行。
await 里的代码在新线程里运行。
同时,被调用的异步函数返回值类型是Task。
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
// 按钮事件
private void BtnTaskAwait_Click(object sender, EventArgs e)
{
Debug.WriteLine("BtnTaskAwait_Click begin.");
ExecuteTask(sender, e);
Debug.WriteLine("BtnTaskAwait_Click end.");
}
// 执行短暂的同步操作,启动异步操作
private async void ExecuteTask(object sender, EventArgs e)
{
Debug.WriteLine($"{GetCurrentThreadId()}");
// 界面线程执行开始
Debug.WriteLine("ExecuteClickTaskAsync begin.");
textBox1.Text = "";
progressBar1.Visible = true;
// 界面线程执行结束
// 在非界面线程执行
await DoSomethingAsync(sender, e);
// 界面线程执行开始
progressBar1.Visible = false;
Debug.WriteLine("ExecuteClickTaskAsync end.");
// 界面线程执行结束
}
// 执行耗时的异步操作
private async Task DoSomethingAsync(object sender, EventArgs e)
{
Debug.WriteLine($"{GetCurrentThreadId()}");
//await Task.Run(() =>
//{
// //Task.Delay(TimeSpan.FromSeconds(5));
// System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
//});
await Task.Run(() =>
{
// 在非界面线程执行,所以不能操作控件
textBox1.Invoke((MethodInvoker)(() =>
{
textBox1.Text = "Task async UI: Sleep 5 second.";
}));
var sw = new Stopwatch();
sw.Start();
while (sw.Elapsed.TotalSeconds < 5)
{
int val = (int)(sw.Elapsed.TotalSeconds / 5 * 100) % 100;
// 在非界面线程执行,所以不能操作控件
progressBar1.Invoke((MethodInvoker)(() =>
{
progressBar1.Value = val;
}));
Task.Delay(TimeSpan.FromMilliseconds(1));
}
// 在非界面线程执行,所以不能操作控件
textBox1.Invoke((MethodInvoker)(() =>
{
textBox1.Text = "Task async UI: Finished.";
}));
});
}
以下为Debug输出,可以看出是异步执行的。
BtnTaskAwait_Click begin.
ExecuteClickTaskAsync begin.
BtnTaskAwait_Click end.
ExecuteClickTaskAsync end.
posted on 2021-07-18 22:00 OctoberKey 阅读(610) 评论(0) 收藏 举报