在我们的程序中,很多时候会有一些耗时较长的运算,我们为了保证用户体验,让用户界面能得到及时的响应。我们一般会采用多线程操作,让耗时操作在
后台完成,比如我们在上传文件或其他一些需求要在界面显示进度条的例子。在 .NET2.0中为我们供了一个BackGroundWorker类可以完成类似的需求,具体
使用我们可以参考MSDN。本文要说的我们自己来完成这样一个功能,并封装在通用的基类当中。
1.我们封装的基类如下:
public abstract class MyAsyncBaseClass { //封装业务方法参数 private class MyMethodParameters { public string StringParameter { get; set; } public int IntParameter { get; set; } public object CallerStateObject { get; set; } public System.Windows.Threading.Dispatcher CallingDispatcher { get; set; } } //当线程执行完成后被激发的事件 public event EventHandler<MyAsyncEventArgs> MyMethodComplete; protected void FireMyMethodCompleteEvent(int result, object state) { if (MyMethodComplete != null) { MyMethodComplete(this, new MyAsyncEventArgs(result, state)); } } //业务逻辑程序 public abstract int MyMethod(string stringParameter, int intParameter); // 异步调用的方法 public void MyMethodAsync(string stringParameer, int intParameter, object state) { //Instantiate the parameter wrapper. MyMethodParameters parameters = new MyMethodParameters() { StringParameter = stringParameer, IntParameter = intParameter, CallerStateObject = state, CallingDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher }; //创建线程 System.Threading.ThreadPool.QueueUserWorkItem(MyMethodThreaded, parameters); } // 线程入口点 private void MyMethodThreaded(object p) { MyMethodParameters parameters = (MyMethodParameters)p; //调用实际的MyMethod方法 int result = MyMethod(parameters.StringParameter, parameters.IntParameter); ///Incorect way to raise event ///This would cause a "Cross-thread operation not valid Exception" ///FireMyMethodCompleteEvent(result, parameters.CallerStateObject); /// ///Correct way to raise event ///Construct a new delegate with the signature <int, object> and register ///it on the caller's event queue. parameters.CallingDispatcher.BeginInvoke( new Action<int, object>(FireMyMethodCompleteEvent), result, parameters.CallerStateObject ); } }
public class MyAsyncEventArgs : EventArgs {
/// 用户状态对象 public object State { get; protected set; } /// 线程操作完的结果 /// </summary> public int IntResult { get; protected set; } public MyAsyncEventArgs(int result, object state) { State = state; IntResult = result; } }
3.我们具体要实现的类如下:
public class MyClass : MyAsyncBaseClass { public override int MyMethod(string stringParameter, int intParameter) { System.Threading.Thread.Sleep(2000); MessageBox.Show("业务逻辑程序执行的地方"); return 42; } }
public partial class Form1 : Form { protected MyAsyncBaseClass class1; public Form1() { InitializeComponent(); class1 = new MyClass(); class1.MyMethodComplete += MyClass_MyMethodComplete; } void MyClass_MyMethodComplete(object sender, MyAsyncEventArgs e) { object userState = e.State; textBox1.Text = String.Format("耗时计算的结果: {0}", e.IntResult); } private void button1_Click(object sender, EventArgs e) { class1.MyMethodAsync("A string parameter", 100, this); } }
作者:生鱼片
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
分类:
DotNet
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
2008-10-18 坚持学习WF(24):WF中的异常处理