首页 > 其他分享 >异步调用方法并弹出处理中窗体(转载)---线程池的封装

异步调用方法并弹出处理中窗体(转载)---线程池的封装

时间:2023-06-07 17:02:45浏览次数:44  
标签:OnInvokeEnding OnInvokeStarting --- 窗体 mProgressFrom Action 线程 處理 public

原文链接:[C#] 非同步呼叫方法並跳出處理中視窗 | 愛流浪的小風 - 點部落 (dotblogs.com.tw)

前言

 

當我們在Winform進行某些比較花時間的運算時,

若沒有使用非同步的方法來呼叫,畫面上的視窗就會顯示沒有回應,

這是一種比較差的使用者體驗,可能會讓使用者以為當機了,

在這邊為了方便重複使用,所以寫了一個Template Class來當作非同步的呼叫媒介,

也可以同時在非同步處理時,跳出提示訊息顯示"處理中"

 

實際演練

 

為了統一非同步的行為,並在處理時顯示同樣的提示視窗,

所以我們撰寫了一個Template Class來處理非同步的邏輯。

 public class AsyncTemplate
    {
        public static Action OnInvokeStarting { get; set; }

        public static Action OnInvokeEnding { get; set; }       

        public static void DoWorkAsync(Action beginAction, Action endAction, Action<Exception> errorAction)
        {            
            ThreadPool.QueueUserWorkItem(new WaitCallback(
                (o) =>
                {
                    try
                    {
                        beginAction();

                        endAction();
                    }
                    catch (Exception ex)
                    {
                        errorAction(ex);
                        return;
                    }
                    finally
                    {
                        if (OnInvokeEnding != null)
                        {
                            OnInvokeEnding();
                        }
                    }
                })
            , null);

            if (OnInvokeStarting != null)
            {
                OnInvokeStarting();
            }
        }

        public static void DoWorkAsync<TResult>(Func<TResult> beginAction, Action<TResult> endAction, Action<Exception> errorAction)
        {            
            ThreadPool.QueueUserWorkItem(new WaitCallback(
                (o) =>
                {
                    TResult result = default(TResult);

                    try
                    {
                        result = beginAction();

                        endAction(result);
                    }
                    catch (Exception ex)
                    {
                        errorAction(ex);
                        return;
                    }
                    finally
                    {
                        if (OnInvokeEnding != null)
                        {
                            OnInvokeEnding();
                        }
                    }
                })
            , null);

            if (OnInvokeStarting != null)
            {
                OnInvokeStarting();
            }
        }
    }

一:在這邊提供了兩個方法來提供非同步的作業,分別是沒有回傳值以及有回傳值

二:在這邊提供了兩個方法來提供非同步的作業,分別是沒有回傳值以及有回傳值

三:在這邊準備了兩個Form,一個Form提供了加法的計算

四:另外一個Form則顯示處理中,以及一個Progress Bar滾動模擬資料處理

(小技巧:將Progress Bar的Style設為Marquee即可獲得如上圖之效果)

Form1的程式碼如下

 public partial class Form1 : Form
    {
        private Form2 mProgressFrom = new Form2();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AsyncTemplate.DoWorkAsync(
                () =>
                {
                    return doWork(int.Parse(textBox1.Text), int.Parse(textBox2.Text));
                },
                (result) =>
                {
                    MessageBox.Show("Success, Result is " + result.ToString());
                },
                (exception) =>
                {
                    MessageBox.Show(exception.Message);
                    //error handling
                });
        }

        private int doWork(int a, int b)
        {

            Thread.Sleep(10000);

            return a + b;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            AsyncTemplate.OnInvokeStarting =
                () =>
                {
                    mProgressFrom.ShowDialog();
                };

            AsyncTemplate.OnInvokeEnding =
                () =>
                {
                    if (mProgressFrom.InvokeRequired)
                    {
                        mProgressFrom.Invoke(new MethodInvoker(
                            ()
                            =>
                            {
                                mProgressFrom.Close();
                            })
                        );
                    }
                    else
                    {
                        mProgressFrom.Close();
                    }
                };
        }
    }

在Form_Load方法中,我們設定了OnInvokeStarting和OnInvokeEnding的屬性,

分別在開始處理時顯示處理中視窗,以及當運算完成時關閉提示視窗。

在doWork方法中,進行的是加法的運算,在這邊為了模擬長時間的運算,

所以我們在此方法中停留了十秒。

而button1_Click方法中使用Template Class來呼叫主要的演算邏輯

 

實際執行程式,我們可以發現達到了我們預期中的效果,

按下計算時,跳出了提示視窗,讓使用者知道正在進行大量的運算,

也不會呈現沒有回應的狀態。

好的使用者體驗,是非常重要的,

不但可以讓使用者使用更順手,也不會誤認程式常常當機,

在.Net中還有許多種非同步的作法,例如BackgroundWorker,

大家可以按照自己在開發時的需求做改變,

在這邊提供了一種實作的方式,也歡迎大家多多指教與討論 ^^

标签:OnInvokeEnding,OnInvokeStarting,---,窗体,mProgressFrom,Action,线程,處理,public
From: https://www.cnblogs.com/Peretsoft/p/17463889.html

相关文章

  • Linux 下启动jmeter 报-bash: bin/jmeter: Permission denied
    问题:通过cd进入jmeter目录中,执行脚本 bin/jmeter-n-txxxxx.jmx -l../50.jtl出现以下问题解决方法:修改文件权限chmod+xbin/jmeter修改后再次执行可正常启动 ......
  • 3D UX-net 训练记录
    3DUX-net训练记录题外话:如果自己跑过nnunet或者其他模型的大佬会更容易上手,但是对于第一次跑模型的小白来说,这个模型也是很好上手和跑通的!本人就是小白,这是我跑通的第一个模型。首先先去官网下载所需的代码和论文(跑之前可以先不看论文,我就是)官网:GitHub-MASILab/3DUX-Net......
  • 氚云--进行空间赋值,页面跳转,弹出新增数据界面框
    一、前端数据赋值场景:进行判断风险等级,单选框自动选中对应等级颜色。解决:先创建一个单行文本进行判断等级颜色,之后前端赋值给单选框debugger;varparent=this;varenviroment=$.SmartForm.ResponseContext;//获取当前对象环境变量parent.F......
  • [转]解决WebService 测试窗体只能用于来自本地计算机的请求
    [转自]原文地址:https://www.cnblogs.com/JuneZhang/archive/2013/01/24/net.html问题:WebService部署成站点之后,如果在本地测试webservice可以运行,在远程却显示“测试窗体只能用于来自本地计算机的请求”或者"Thetestformisonlyavailableforrequestsfromthelocalma......
  • java面试(30)- redis
    1:Redis支持的数据类型a)字符串keyvalb)hashkeynamefiledc)listkeyv1v2v3v3d)setkeyv1v2v3d)zsetkeysv2:Redis支持的事务3:为什么redis快 4:redis的优缺点1、优点a)数据类型丰富b)支持数据......
  • 解决Ubuntu 20.04升级后gnome-control-center设置程序无法打开问题
    解决Ubuntu20.04升级后gnome-control-center设置程序无法打开问题Ubuntu20.04系统升级后,发现gnome设置程序无法正常打开了。在终端运行命令查看错误信息,运行以下命令:sudognome-control-center从显示的错误信息可以看出,其调用的一些so文件,需要高版本的libc6,而Ubuntu20.0......
  • LDGRB-01 3BSE013177R1 ABB模块 DCS S800I/O 全新
    LDGRB-013BSE013177R1ABB模块DCSS800I/O全新LDGRB-013BSE013177R1ABB模块DCSS800I/O全新 什么是仪器仪表中的基金会现场总线?与传统概念相比,现场总线有哪些优势?什么是仪器仪表中的基金会现场总线? 基础现场总线是一种串行、双向、全数字网络,用作工厂或工厂自动......
  • Deep One-Class Classification
    DeepOne-ClassClassifificationDeepSVDD(DeepSupportVectorDataDescription)训练一个神经网络,最小化包含数据表征的超球的体积(如图1所示)DeeoSVDD的目标函数soft-boundaryDeepSVDD输入空间\(\mathcal{X}\subseteq\mathbb{R}^d\)和输出空间\(\mathcal{F}\subs......
  • 线程同步:Lock锁
        ......
  • vue之vue-cli创建项目、vue项目目录结构、vue项目编写规范、 es6导入导出语法
    目录一、vue-cli创建项目1.1、背景知识单页面应用:spa单文件组件(一个组件一个文件)一个组件中有的东西使用vue-cli创建vue项目,才能使用单文件组件vue-cli脚手架,1.2使用vue-cli创建vue项目1.3vue-cli创建项目vue-cli命令行创建项目使用vue-cli-ui创建运行vue项目方式一:命令行中......