C# 多线程问题处理小结

这两天用到一个需要使用多线程的问题,纠结了一天终于解决了!

问题描述:程序启动后,需要解析文件,由于文件太大,所以解析中会使程序卡顿,故需要额外弹出一个Loading窗体显示“Loading...”(可以用动态图或者进程条),同时文件依旧解析,解析好了就关掉Loading窗体。

问题分析:Loading窗体是由主线程new出来的,所以在Loading窗体关闭前主线程都被用着,而且解析文件是个I/O操作,很耗时,所以必须使用多线程解决了!

解决方案:一、BackgroundWorker异步操作;二、多线程

一、微软为我们提供了BackgroundWorker组件,BackgroundWorker是.net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。

代码:private static System.ComponentModel.BackgroundWorker backgroundWorker1;
backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
以上为定义BackgroundWorker ,backgroundWorker1_DoWork为启动该组件后执行的方法,该方法肯定是用来处理你那些耗时的东东了,backgroundWorker1_RunWorkerCompleted为该组件完成自己任务后最后执行的方法,相当于收尾工作。

至于使用的话很简单,在你准备异步处理的函数里backgroundWorker1.RunWorkerAsync();就行了,为了弹出Loading窗体,可以在后边加上这些代码Loading form = new Loading(backgroundWorker1); form.ShowDialog();

new Loading(backgroundWorker1)中的backgroundWorker1作用是为了在Loading的构造函数里为backgroundWorker1.RunWorkerCompleted 注册一个关闭窗体的函数,这样一来这个处理的流程就变成了这样:主线程创建了一个线程执行耗时操作,而自己调用了Loading窗体来避免程序卡顿的尴尬,等线程执行完耗时操作后自动调用了窗体的关闭函数结束自身,当窗体关闭后主线程就可以接着干自己的事情了。Done!

二、多线程

其实BackgroundWorker就类似于一个线程,只不过微软把它封装的很好,省了我们很多麻烦,同样这个问题我们也可以用多线程处理。

处理的思路大体一样:在需要执行耗时操作时创建一个线程来干,主线程自己调用Loading窗体,耗时操作完了后回调把Loading窗体关了,然后主线程恢复自由。

代码:Thread thread = new Thread(new ThreadStart(work));

thread.start();

Loading form = new Loading();

form.showDialog();

work()里就是执行耗时操作的东东

注意,在使用BackgroundWorker 时,我们直接使用其事件RunWorkerCompleted,给它注册一个关闭Loading窗体函数,但是多线程方法处理时就得自己动手了,方法是使用委托,public delegate void CloseFormEventHander(); public event CloseFormEventHander CloseForm;在Loading构造函数中给CloseForm注册关闭函数。

如何调用关闭函数呢,一般情况下在work()中加上CLoseForm()可是不行的,CloseForm是在次线程中调用的,而Loading窗体是在主线程创建的,会报错。我们应该在work()里使用form.invoke(CloseForm,null);回调就OK了!

这篇文章写得有点急,可能不流畅,需要交流的请留言吧!见谅!

阅读更多

没有更多推荐了,返回首页