c#多线程耗时操作不卡界面的顺序流程处理方式
By
admin
at 2021-01-06 • 0人收藏 • 1332人看过
这里新建了method.cs类库, 在类库中需要实时更新数据输出到form1界面中的lable1控件上面 , 我们需要在界面form1中调用此类库, 来执行一个耗时流程.
我们知道在c#里为了不卡界面就需要开多线程 , 多线程里想要更新界面UI控件就需要用到委托 , 看了一些文章发现写的基本千篇一律, 都是在同一个form界面中进行的委托定义和使用, 实际使用中却并不如此, 像我上面的需求, 那么在method类中应该怎么处理才能最简单直接呢?
经过了多次测试, 我发现下面的写法应该是最直观和简单的办法.
我在method中定义一个委托函数, 在form1界面中将这个函数给赋值, 代码如下:
method.cs代码如下:
using System; using System.Threading; using System.Threading.Tasks; namespace WindowsFormsApp2 { internal class Method { //定义一个全局委托函数 public static Action<string> WriteStr; //手动停止 public static bool HandStop { get; set; } //耗时函数实例 public static bool demoFunc() { var FindOK = false; var tsk = Task.Run(() => { for (int i = 0; i < 100; i++) { WriteStr(i.ToString()); if (HandStop) { FindOK = false; break; } if (i>40) { FindOK = true; break; } Thread.Sleep(100); } }); tsk.Wait(); return FindOK; } } }
form1.cs界面代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApp2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { Method.HandStop = false; //方式一: 先定义,再使用 //Action<string> action1 = (str) => //{ // Action action = () => // { // label1.Text = str; // }; // this.BeginInvoke(action); //}; //Method.WriteStr = action1; //方式二: 直接赋值定义使用 Method.WriteStr = (str) => { Action action = () => { label1.Text = str; }; this.BeginInvoke( action ); }; //任务内部会自动调用上面的委托 var tsk = Task.Run(() => { var ret = Method.demoFunc( ) ; }); //等待任务完成 await tsk; Console.WriteLine("ok"); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { Method.HandStop = true; } private void button3_Click(object sender, EventArgs e) { Method.HandStop = true; } } }
代码工程如下:
开线程无限刷新界面实例:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; namespace WindowsFormsApp2 { public partial class Form1 : Form { //全局定义 Action<string> loopStr; public Form1() { InitializeComponent(); //函数初始化 loopStr = (str) => { Action action = () => { label2.Text = str; }; this.BeginInvoke(action); }; } private void Form1_Load(object sender, EventArgs e) { Method.HandStop = false; Task.Run(() => { var i = 0; while (!Method.HandStop) { //调用 loopStr(i.ToString()); Thread.Sleep(100); i++; } Console.WriteLine("loop end"); }); } private void button3_Click(object sender, EventArgs e) { Method.HandStop = true; } } }
using System; using System.Threading; using System.Threading.Tasks; namespace WindowsFormsApp2 { internal class Method { //定义一个全局委托函数 public static Action<string> WriteStr; //手动停止 public static bool HandStop { get; set; } //耗时函数实例 public static bool demoFunc() { var FindOK = false; var tsk = Task.Run(() => { for (int i = 0; i < 100; i++) { WriteStr(i.ToString()); if (HandStop) { FindOK = false; break; } if (i>40) { FindOK = true; break; } Thread.Sleep(100); } }); tsk.Wait(); return FindOK; } } }
C#调用dll方法
//第一步,添加dll运行库 using System.Runtime.InteropServices; //第二步, [DllImport("Demo.dll", EntryPoint = "demo_init", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern UInt16 demo_init(); [DllImport("Demo.dll", EntryPoint = "demo_read_inbit", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern Int32 demo_read_inbit(UInt16 cardno, UInt16 bitno);
3 个回复 | 最后更新于 2024-03-02
![admin](/upload/avatar/middle/1.png)
admin
2024-02-19
#1
登录后方可回帖