-- winform .net core中跨线程修改UI界面与Task,MethodInvoker的应用
【官网】:无
应用场景
多个线程竞争读写同一个资源往往会造成意外结果甚至异常,winform(包括winform .net core)UI界面也是一种资源,所以跨线程修改UI界面经常会抛异常。该问题下我们可以采用Task + MethodInvoker的方式完成跨线程对UI对的修改。基础资源
.net core 3.1或.net framework 4.5及以上
使用须知
使用Task.Wait时,建议都加上ConfigureAwait(false)防止卡死,当然更好的办法是把相关的方法变成异步的。
配置步骤
无
常见问题
快速入门
A)示例1-后台线程或Task修改界面操作.
/// <summary>
/// 功能简介:封装一个对UI界面的操作(支持跨线程调用)
/// 作者: http://config.net.cn
/// 创建时间:2022-1-8
/// </summary>
/// <param name="action"></param>
private void OnResponseForUI(string action)
{
MethodInvoker method = delegate
{
if (action == "DownLoad")
btnSendEmail.Enabled = false;
else if (action == "Finish_DownLoad")
btnSendEmail.Enabled = true;
};
BeginInvoke(method);
}
/// 功能简介:一个基于后台异步任务的操作,操作过程可以修改UI界面
/// 作者: http://config.net.cn
/// 创建时间:2022-1-8
private void btnStartDownLoad_Click(object sender, EventArgs e)
{
OnResponseForUI("DownLoad");
Task task = new Task(async delegate
{
try
{
await Download();//耗时的或者会阻塞的操作(可以放到子线程,也可以放到Task中
}
catch (Exception ex)
{
TipsCrossThread(ex.Message + "," + ex.StackTrace);
}
OnResponseForUI("Finish_DownLoad");
});
task.Start();
}
A2)示例2-创建一个TaskEngine,并实现开启,停止等。
public class MetaTaskEngine
{
private Task _task;
private CancellationTokenSource _cancellationTokenSource;
private MetaTaskEngine()
{
//todo:实现任务处理的初始化 }
private void WorkProcess(){
//todo:处理任务的实际工作
}
public void Stop()
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}
}
public void Start(MetaTask task)
{
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}
if (_task != null)
{
try
{
_task.Dispose();
}
catch (Exception ex)
{
//todo: exception process
}
}
_cancellationTokenSource = new CancellationTokenSource();
_task = new Task(delegate
{
WorkProcess();
}, _cancellationTokenSource.Token);
_task.Start();
//注:还可以使用下列语句来判断Task的执行状态
if (_task.IsCompletedSuccessfully)//任务成功 {
Console.WriteLine("_task.IsCompletedSuccessfully"); } if (_task.IsCompleted)//任务完成 {
Console.WriteLine("_task.IsCompleted");
}
}
}