文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

一、工具类代码

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

到此这篇关于C#多线程异步执行和跨线程访问控件Helper的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯