c#多线程耗时操作不卡界面的顺序流程处理方式

By admin at 2021-01-06 • 0人收藏 • 733人看过

这里新建了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;
        }

    }
}


代码工程如下:

WindowsFormsApp2.zip


开线程无限刷新界面实例:

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



登录后方可回帖

登 录
信息栏
公 告:

原域名已转让

临时更换为

Aardio.com.cn

请相互转告!



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 popdes@126.com

友情链接
Aardio官方     |     Aardio官方更新日志
Stm32cube中文网
Sciter在线学习文档
才仁机械


打赏本站
Loading...