软件编程
位置:首页>> 软件编程>> C#编程>> C#多线程异步执行和跨线程访问控件Helper

C#多线程异步执行和跨线程访问控件Helper

作者:農碼一生  发布时间:2022-02-09 12:24:32 

标签:C#,多线程,异步,执行,跨线程,访问,Helper,控件

一、工具类代码

public class TaskHelper
   {

#region 多线程操作
       /// <summary>
       /// 功能描述:多线程执行方法,方法无参数,无返回值
       /// </summary>
       /// <param name="func">方法,如果方法中调用了控件,请使用 ThreadInvokerControl(() => { 您的操作})进行包括</param>
       /// <param name="callback">执行完成回调,参数为object,如果错误返回的是Exception,否则为null,如果为空则默认调用基类回调方法</param>
       /// <param name="enableControl">调用线程时禁用的控件</param>
       public static void TaskRun(
         Form frm,
         Func<Task> func,
         Action<object> callback = null,
         Control[] enableControl = null)
       {
           if (enableControl != null)
           {
               SetControlEnableds(enableControl, false);
           }

Task.Factory.StartNew(() =>
           {
               try
               {
                   Task task = func();
                   if (task.Exception != null && task.Exception.InnerException != null)
                       throw task.Exception.InnerException;
                   callback?.Invoke(null);
               }
               catch (Exception ex)
               {
                   if (callback != null)
                       callback(ex);
                   else
                       ThreadBaseCallBack(frm, ex);
               }
               finally
               {
                   if (enableControl != null && frm != null)
                       ThreadInvokerControl(frm, () => { SetControlEnableds(enableControl, true); });
               }
           });
       }

/// <summary>
       /// 功能描述:线程默认回调方法
       /// </summary>
       public static void ThreadBaseCallBack(Form frm, Exception ex)
       {
           if (frm != null)
           {
               ThreadInvokerControl(frm, () =>
               {
                   try
                   {
                       Exception lastEx = ex.GetOriginalException();
                       MessageBox.Show(lastEx.Message);
                   }
                   catch
                   {

}
               });
           }
       }

/// <summary>
       /// 功能描述:委托调用,用于夸线程访问控件
       /// </summary>
       /// <param name="action">action</param>
       /// <param name="f">所在窗体,默认使用当前窗体</param>
       public static void ThreadInvokerControl(Form frm, Action action)
       {
           if (frm != null)
           {
               if (frm.InvokeRequired)
               {
                   frm.BeginInvoke(action);
               }
               else
               {
                   action();
               }
           }
       }

#endregion

#region 提示层
       [DllImport("user32.dll")]
       private static extern bool SetForegroundWindow(IntPtr hWnd);
       private static void ShowProcessPanel(Control parent, string strMessage)
       {
           if (parent.InvokeRequired)
           {
               parent.BeginInvoke(new MethodInvoker(delegate
               {
                   ShowProcessPanel(parent, strMessage);
               }));
           }
           else
           {
               parent.VisibleChanged -= new EventHandler(parent_VisibleChanged);
               parent.VisibleChanged += new EventHandler(parent_VisibleChanged);
               parent.FindForm().FormClosing -= ControlHelper_FormClosing;
               parent.FindForm().FormClosing += ControlHelper_FormClosing;
               Control control = null;
               lock (parent)
               {
                   control = HaveProcessPanelControl(parent);
                   if (control == null)
                   {
                       control = CreateProgressPanel();
                       parent.Controls.Add(control);
                   }
               }
               FWaiting fWaiting = control.Tag as FWaiting;
               fWaiting.Message = strMessage;
               fWaiting.Show();
           }
       }
       private static void ControlHelper_FormClosing(object sender, FormClosingEventArgs e)
       {
           Control control = sender as Control;
           control.FindForm().FormClosing -= ControlHelper_FormClosing;
           CloseWaiting(control);
       }

private static void parent_VisibleChanged(object sender, EventArgs e)
       {
           Control control = sender as Control;
           control.VisibleChanged -= new EventHandler(parent_VisibleChanged);
           if (!control.Visible)
           {
               CloseWaiting(control);
           }
       }
       private static void CloseWaiting(Control control)
       {
           Control[] array = control.Controls.Find("myProgressPanelext", false);
           if (array.Length > 0)
           {
               Control myProgress = array[0];
               if (myProgress.Tag != null && myProgress.Tag is FWaiting)
               {
                   FWaiting fWaiting = myProgress as FWaiting;
                   if (fWaiting != null && !fWaiting.IsDisposed && fWaiting.Visible)
                   {
                       fWaiting.Hide();
                   }
               }
           }
       }
       private static void CloseProcessPanel(Control parent)
       {
           if (parent.InvokeRequired)
           {
               parent.BeginInvoke(new MethodInvoker(delegate
               {
                   CloseProcessPanel(parent);
               }));
           }
           else if (parent != null)
           {
               Control control = HaveProcessPanelControl(parent);
               if (control != null)
               {
                   Form frm = control.Tag as Form;
                   if (frm != null && !frm.IsDisposed && frm.Visible)
                   {
                       if (frm.InvokeRequired)
                       {
                           frm.BeginInvoke(new MethodInvoker(delegate
                           {
                               frm.Hide();
                           }));
                       }
                       else
                       {
                           frm.Hide();
                       }
                   }
               }
           }
       }
       private static Control HaveProcessPanelControl(Control parent)
       {
           Control[] array = parent.Controls.Find("myProgressPanelext", false);
           Control result;
           if (array.Length > 0)
           {
               result = array[0];
           }
           else
           {
               result = null;
           }
           return result;
       }
       private static Control CreateProgressPanel()
       {
           return new Label
           {
               Name = "myProgressPanelext",
               Visible = false,
               Tag = new FWaiting
               {
                   TopMost = true,
               }
           };
       }
       #endregion

#region 禁用控件时不改变空间颜色
       [System.Runtime.InteropServices.DllImport("user32.dll ")]
       private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc);
       [System.Runtime.InteropServices.DllImport("user32.dll ")]
       private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

private const int GWL_STYLE = -16;
       private const int WS_DISABLED = 0x8000000;

/// <summary>
       /// 功能描述:设置控件的Enable属性,控件不改颜色
       /// </summary>
       /// <param name="c">c</param>
       /// <param name="enabled">enabled</param>
       private static void SetControlEnabled(Control c, bool enabled)
       {
           if (enabled)
           {
               SetWindowLong(c.Handle, GWL_STYLE, (~WS_DISABLED) & GetWindowLong(c.Handle, GWL_STYLE));
           }
           else
           {
               SetWindowLong(c.Handle, GWL_STYLE, WS_DISABLED + GetWindowLong(c.Handle, GWL_STYLE));
           }
       }

/// <summary>
       /// 功能描述:设置多个控件的Enable属性,控件不改颜色
       /// </summary>
       /// <param name="cs">cs</param>
       /// <param name="enabled">enabled</param>
       private static void SetControlEnableds(Control[] cs, bool enabled)
       {
           foreach (var c in cs)
           {
               SetControlEnabled(c, enabled);
           }
       }
       #endregion
   }

二、调用代码

TaskHelper.TaskRun(this, async () =>
           {
               TaskHelper.ThreadInvokerControl(this, () =>
               {
                   //夸线程访问控件的
                   this.btnStart.Enabled = true;
                   this.btnStart.BackColor = Color.Gainsboro;
               });
           });

来源:https://www.cnblogs.com/wml-it/p/15607362.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com