天天看點

多線程異步執行和跨線程通路控件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

技術的發展日新月異,随着時間推移,無法保證本部落格所有内容的正确性。如有誤導,請大家見諒,歡迎評論區指正! 個人開源代碼連結: GitHub:

https://github.com/ITMingliang

Gitee:

https://gitee.com/mingliang_it

GitLab:

https://gitlab.com/ITMingliang

進開發學習交流群:
多線程異步執行和跨線程通路控件Helper

繼續閱讀