winform (含.net framewor和net core)跨线程修改UI界面与Task的应用

-- 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");
            }
} }




参考资料