内容补充:浅述WinForm多线程编程与Control.Invoke的应用
前几天我转载了一篇随笔《浅述WinForm多线程编程与Control.Invoke的应用》,有博友反映说问题没有说到点上,我在这里为此做一个解释:随笔是别人写的,我想尊重原创的意愿、所以我也没有那篇随笔做任何更改。 还有,那篇随笔更加侧重的是知识点,而不是实例。
步入正题.
为了解决窗体卡死的问题,我常用的是如下的两种策略:
1、就是前文提到的 多线程 + Invoke
2、BackgroundWorker 组件
策略1优点就是 较灵活、适用更广泛,几乎可以用于解决任意情况下窗体卡死;而其缺点:需要自己额外编写许多代码、相对于策略2较为不方便。
相对而言、我还是较青睐于策略2,毕竟方便嘛,可以少写一些Code了。
分享我自己写的一个封装了BackgroundWorker的小窗体:
窗体描述:
一个Lable 用于显示提示语。
一个Button用于取消后台操作。
一个ProgressBar 用于动态滚动,还有个Timer配合提示语使用。
当然以上 都是 纯属交互式设计的一些东东、没什么实际意义。
封装代码如下:
publicpartialclass FrmTipPrompt : Form
{
#region Field And Property
private Func<BackgroundWorker, DoWorkEventArgs, object> mDoWorkHandler;
private Action<RunWorkerCompletedEventArgs> mCompletedHandler;
privateobject mArgument;
privatestring mDialogTip;
privatestring mMsg;
privateint mLen;
private RunWorkerCompletedEventArgs mCompletedResult;
///<summary>
/// 只读
///</summary>
public RunWorkerCompletedEventArgs CompletedResult
{
get { return mCompletedResult; }
}
publicstring Msg
{
get { return mMsg; }
}
#endregion
#region Construct
public FrmTipPrompt()
{
InitializeComponent();
}
#endregion
#region Public Method
publicvoid 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
privatevoid backWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (this.mDoWorkHandler !=null)
{
e.Result =this.mDoWorkHandler(this.backWorker, e);
}
}
privatevoid backWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
privatevoid backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.mCompletedResult = e;
if (this.mCompletedHandler !=null)
{
this.mCompletedHandler(e);
}
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
privatevoid FrmTipPrompt_Load(object sender, EventArgs e)
{
this.timerTip.Enabled =true;
this.timerTip.Interval =500;
this.backWorker.RunWorkerAsync(this.mArgument);
this.btnCancel.Focus();
}
privatevoid timerTip_Tick(object sender, EventArgs e)
{
this.mLen++;
this.mLen %=6;
this.lblTip.Text =string.Format("{0}{1}", this.mDialogTip, newstring(char.Parse("."), this.mLen));
}
privatevoid btnCancel_Click(object sender, EventArgs e)
{
this.backWorker.CancelAsync();
}
privatevoid FrmTipPrompt_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
this.backWorker.CancelAsync();
}
}
#endregion
}
{
#region Field And Property
private Func<BackgroundWorker, DoWorkEventArgs, object> mDoWorkHandler;
private Action<RunWorkerCompletedEventArgs> mCompletedHandler;
privateobject mArgument;
privatestring mDialogTip;
privatestring mMsg;
privateint mLen;
private RunWorkerCompletedEventArgs mCompletedResult;
///<summary>
/// 只读
///</summary>
public RunWorkerCompletedEventArgs CompletedResult
{
get { return mCompletedResult; }
}
publicstring Msg
{
get { return mMsg; }
}
#endregion
#region Construct
public FrmTipPrompt()
{
InitializeComponent();
}
#endregion
#region Public Method
publicvoid 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
privatevoid backWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (this.mDoWorkHandler !=null)
{
e.Result =this.mDoWorkHandler(this.backWorker, e);
}
}
privatevoid backWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
privatevoid backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.mCompletedResult = e;
if (this.mCompletedHandler !=null)
{
this.mCompletedHandler(e);
}
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
privatevoid FrmTipPrompt_Load(object sender, EventArgs e)
{
this.timerTip.Enabled =true;
this.timerTip.Interval =500;
this.backWorker.RunWorkerAsync(this.mArgument);
this.btnCancel.Focus();
}
privatevoid timerTip_Tick(object sender, EventArgs e)
{
this.mLen++;
this.mLen %=6;
this.lblTip.Text =string.Format("{0}{1}", this.mDialogTip, newstring(char.Parse("."), this.mLen));
}
privatevoid btnCancel_Click(object sender, EventArgs e)
{
this.backWorker.CancelAsync();
}
privatevoid 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>
publicint Loading(UserLogin userLogin, refstring 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)
{
return1;
}
int mLoginResult =1;
if (!int.TryParse(e.Result.ToString(), out mLoginResult))
{
return1;
}
return mLoginResult;
}
}
/// 登录方法
/// 0:成功 -1:失败 1:取消登录 -2:联网登录用户名或密码错误 -3:网络异常 且 用户名或密码错误
///</summary>
///<param name="userLogin">用户名密码</param>
///<param name="strMsg">登录失败时的错误信息</param>
///<returns>返回登录结果 </returns>
publicint Loading(UserLogin userLogin, refstring 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)
{
return1;
}
int mLoginResult =1;
if (!int.TryParse(e.Result.ToString(), out mLoginResult))
{
return1;
}
return mLoginResult;
}
}
由于代码比较简单 我就不再额外加注释喽。
引用地址:http://www.cnblogs.com/08shiyan/archive/2011/05/16/2047658.html


浙公网安备 33010602011771号