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
投稿
猜你喜欢
- 1、深度总结引用一位网友的话,说的非常好,如果别人问你static的作用;如果你说静态修饰 类的属性 和 类的方法 别人认为你是合格的;如果
- 现阶段的问题现在是云原生和容器化时代,.NET Core对于云原生来说有非常好的兼容和亲和性,dotnet社区以及微软为.NET Core提
- 要求: * 判断用户输入的年份是平年还是闰年实现代码:import java.util.Scanner;/** * 要
- 熔断与降级为什么在RPC环节中有熔断以及降级的需求,详细的原因这里不多解释,从网上搜索一张图做示意。熔断我理解熔段主要解决如下几个问题:当所
- 本文实例为大家分享了java实现字符串反转的具体代码,供大家参考,具体内容如下1.需求:定义一个方法,实现字符串反转。键盘录入一个字符串,调
- 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三
- 前言本文章主要从spring security安全认证登录内部调用流程来流程分析登录过程。一、登录时序图时序原图二、配置与代码1.引入库po
- 在mybatis中sql是写在xml映射文件中的,如果sql中有一些特殊字符的话,在解析xml文件的时候就会被转义,如若不希望被转义,那该怎
- 紧接上文所述,在这篇文章中我将对Mapper映射文件进行详细的说明。Mapper映射文件是一个xml格式文件,必须遵循相应的dtd文件规范,
- java文件打包jar运行有效步骤:1.cmd 到当前目录(默认包主类所在目录为例) set classpath = 默认包主类所在目录2.
- 面试官:sychronized关键字有哪些特性?应聘者:可以用来修饰方法;可以用来修饰代码块;可以用来修饰静态方法;可以保证线程安全;支持锁
- 一、return语句执行顺序finally语句是在return语句执行之后,return语句返回之前执行的package exception
- 概述从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章.链表链表 (Linked List) 是一种递归的动态数
- <%@ page language="java" contentType="text/html; cha
- 本文实例为大家分享了Unity2D游戏回旋镖实现的具体代码,供大家参考,具体内容如下以下我举出2种同使用情况的回旋镖那么回旋镖需要怎么做呢?
- Reflections通过扫描classpath,索引元数据,并且允许在运行时查询这些元数据。使用Reflections可以很轻松的获取以下
- 如何在原有日期时间上加几个月或几天在原有的时间上添加几个月SimpleDateFormat df = new SimpleDateForma
- 本文实例讲述了Java实现合并两个有序序列算法。分享给大家供大家参考,具体如下:问题描述输入:序列A<a0,a1,a2,...aq,a
- Java 使用getClass().getResourceAsStream()方法获取资源之前想获取一个资源文件做一些处理,使用getCla
- 概述从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章.字符串匹配字符串匹配 (String Matching)