zoukankan      html  css  js  c++  java
  • 内容补充:浅述WinForm多线程编程与Control.Invoke的应用

    前几天我转载了一篇随笔《浅述WinForm多线程编程与Control.Invoke的应用》,有博友反映说问题没有说到点上,我在这里为此做一个解释:随笔是别人写的,我想尊重原创的意愿、所以我也没有那篇随笔做任何更改。 还有,那篇随笔更加侧重的是知识点,而不是实例。

    步入正题.

    为了解决窗体卡死的问题,我常用的是如下的两种策略:

    1、就是前文提到的 多线程 + Invoke

    2、BackgroundWorker 组件

    策略1优点就是 较灵活、适用更广泛,几乎可以用于解决任意情况下窗体卡死;而其缺点:需要自己额外编写许多代码、相对于策略2较为不方便。

    相对而言、我还是较青睐于策略2,毕竟方便嘛,可以少写一些Code了。

    分享我自己写的一个封装了BackgroundWorker的小窗体:

    窗体描述:

    一个Lable 用于显示提示语。

    一个Button用于取消后台操作。

    一个ProgressBar 用于动态滚动,还有个Timer配合提示语使用。
    当然以上 都是 纯属交互式设计的一些东东、没什么实际意义。

    封装代码如下:

    public partial class FrmTipPrompt : Form
    {
    #region Field And Property

    private Func<BackgroundWorker, DoWorkEventArgs, object> mDoWorkHandler;

    private Action<RunWorkerCompletedEventArgs> mCompletedHandler;

    private object mArgument;

    private string mDialogTip;

    private string mMsg;

    private int mLen;

    private RunWorkerCompletedEventArgs mCompletedResult;

    /// <summary>
    /// 只读
    /// </summary>
    public RunWorkerCompletedEventArgs CompletedResult
    {
    get { return mCompletedResult; }
    }

    public string Msg
    {
    get { return mMsg; }
    }

    #endregion


    #region Construct

    public FrmTipPrompt()
    {
    InitializeComponent();
    }

    #endregion


    #region Public Method

    public void SetParam(
    Func
    <BackgroundWorker, DoWorkEventArgs, object> doWorkHandler,
    Action
    <RunWorkerCompletedEventArgs> completedHandler,
    object argument,
    string strDialogTip)
    {

    this.mDoWorkHandler = doWorkHandler;
    this.mCompletedHandler = completedHandler;
    this.mArgument = argument;
    if (strDialogTip == null)
    {
    this.mDialogTip = "请稍后";
    }
    else
    {
    this.mDialogTip = strDialogTip;
    }
    this.mLen = 1;
    }

    #endregion


    #region Event Method

    private void backWorker_DoWork(object sender, DoWorkEventArgs e)
    {
    if (this.mDoWorkHandler != null)
    {
    e.Result
    = this.mDoWorkHandler(this.backWorker, e);
    }

    }

    private void backWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {

    }

    private void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    this.mCompletedResult = e;
    if (this.mCompletedHandler != null)
    {
    this.mCompletedHandler(e);
    }
    this.DialogResult = System.Windows.Forms.DialogResult.OK;
    }

    private void FrmTipPrompt_Load(object sender, EventArgs e)
    {
    this.timerTip.Enabled = true;
    this.timerTip.Interval = 500;
    this.backWorker.RunWorkerAsync(this.mArgument);
    this.btnCancel.Focus();
    }

    private void timerTip_Tick(object sender, EventArgs e)
    {
    this.mLen++;
    this.mLen %= 6;

    this.lblTip.Text = string.Format("{0}{1}", this.mDialogTip, new string(char.Parse("."), this.mLen));
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
    this.backWorker.CancelAsync();
    }

    private void FrmTipPrompt_FormClosing(object sender, FormClosingEventArgs e)
    {
    if (e.CloseReason == CloseReason.UserClosing)
    {
    this.backWorker.CancelAsync();
    }
    }

    #endregion

    }

    代码调用:以登录为例。

    /// <summary>
    /// 登录方法
    /// 0:成功 -1:失败 1:取消登录 -2:联网登录用户名或密码错误 -3:网络异常 且 用户名或密码错误
    /// </summary>
    /// <param name="userLogin">用户名密码</param>
    /// <param name="strMsg">登录失败时的错误信息</param>
    /// <returns>返回登录结果 </returns>
    public int Loading(UserLogin userLogin, ref string strMsg)
    {
    strMsg
    = "";
    using (FrmTipPrompt frm = new FrmTipPrompt())
    {
    frm.Width
    = 375;
    frm.SetParam(
    this.LoadingPrompt, userLogin, "登录中");
    frm.ShowDialog();

    RunWorkerCompletedEventArgs e
    = frm.CompletedResult;
    strMsg
    = frm.Msg;

    if (e.Cancelled || e.Result == null)
    {
    return 1;
    }

    int mLoginResult = 1;
    if (!int.TryParse(e.Result.ToString(), out mLoginResult))
    {
    return 1;
    }

    return mLoginResult;
    }
    }

    由于代码比较简单 我就不再额外加注释喽。



    返回导读目录,阅读更多随笔



    分割线,以下为博客签名:

    软件臭虫情未了
    • 编码一分钟
    • 测试十年功


    随笔如有错误或不恰当之处、为希望不误导他人,望大侠们给予批评指正。

  • 相关阅读:
    c# excel sheep 导出
    C# 导出 excel 复杂格式 html导出
    C# 导出CSV功能记录下
    怎样查看修改sqlserver数据库的编码格式
    entity framework如何控制并发
    IT技术 | 让程序员抓狂的排序算法教学视频
    关于高性能的那点事
    论C#逼格手册
    numpy.loadtxt用法
    numpy中np.c_和np.r_
  • 原文地址:https://www.cnblogs.com/08shiyan/p/2047658.html
Copyright © 2011-2022 走看看