通用的异步处理类和进度通知类及其示例
生活随笔
收集整理的這篇文章主要介紹了
通用的异步处理类和进度通知类及其示例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在上文《我的界面進度條異步顯示模式》中,我提到了使用異步處理顯示進度條的時候,我覺得用起來比較順手的一種組織代碼的方法,相比起來,這種方法的最大特點就是把代碼盡量地從界面層剝離,并且讓界面之間的關聯盡可能少些。
我在處理過程中使用了一個封裝了異步線程處理的一個抽象類,這個抽象類實現了異步處理的 Start,Abort, Pause 和 Resume 接口,大家用它來實現異步處理的時候,就可以象玩秒表一樣隨意地控制這些處理過程了。完整的代碼如下:
????public?abstract?class?AsyncWorker
????{
????????public?enum?WorkState{Ready,?Working,?Pause,Resume,Aborted,?Done,?Error}
????????private?WorkState?m_State;
????????private?bool?m_Wait;
????????private?Thread?m_Thread;
????????protected?AsyncWorker(bool?wait)
????????{
????????????m_State?=?WorkState.Ready;
????????????m_Wait?=?wait;
????????????m_Thread?=?new?Thread(new?ThreadStart(Work));
????????}
????????public?void?Start()
????????{
????????????OnStateChangedSync(WorkState.Ready);
????????????m_Thread.Start();
????????????while(?m_Wait?&&?m_Thread.IsAlive?)
????????????{
????????????????OnIdle();
????????????????Thread.Sleep(200);
????????????}
????????}
????????public?void?Pause()
????????{
????????????if(?m_State?==?WorkState.Working)
????????????{
????????????????m_Thread.Suspend();
????????????????m_State?=?WorkState.Pause;
????????????????OnStateChanged(WorkState.Pause);
????????????}
????????}
????????public?void?Resume()
????????{
????????????if(?m_State?==?WorkState.Pause?)
????????????{
????????????????m_State?=?WorkState.Working;
????????????????m_Thread.Resume();
????????????????OnStateChanged(WorkState.Resume);
????????????}
????????}
????????public?void?Abort()
????????{
????????????if(?m_State?==?WorkState.Working?||?m_State?==?WorkState.Pause?)
????????????{
????????????????m_Thread.Abort();
????????????????m_State?=?WorkState.Aborted;
????????????????OnStateChanged(WorkState.Aborted);
????????????}
????????}
????????private?void?Work()
????????{
????????????try
????????????{
????????????????m_State?=?WorkState.Working;
????????????????OnStateChangedSync(WorkState.Working);
????????????????DoWork();
????????????????m_State?=?WorkState.Done;
????????????????OnStateChanged(WorkState.Done);
????????????}
????????????catch?(Exception?e)
????????????{
????????????????m_State?=?WorkState.Error;
????????????????OnError(e);
????????????????OnStateChanged(WorkState.Error);
????????????}
????????}
????????protected?abstract?void?DoWork();
????????private?void?OnStateChangedSync(WorkState?state)
????????{
????????????if(?StateChanged?!=?null?)
????????????????StateChanged(this,?state);
????????}
????????private?void?OnStateChanged(WorkState?state)
????????{
????????????if(?StateChanged?!=?null?)
????????????????StateChanged.BeginInvoke(this,?state,?null,?null);
????????}
????????protected?void?OnIdle()
????????{
????????????if(?Idle?!=?null?)
????????????{
????????????????lock(this)????????//?有可能會很高頻率調用
????????????????????Idle(this);
????????????}
????????}
????????protected?void?OnError(Exception?e)
????????{
????????????if(?Error?!=?null?)
????????????????Error.BeginInvoke(this,?e,?null,?null);
????????}
????????public?delegate?void?StateChangedEventHandler(AsyncWorker?sender,?WorkState?state);
????????public?delegate?void?IdleEventHandler(AsyncWorker?sender);
????????public?delegate?void?ErrorEventHandler(AsyncWorker?sender,?Exception?e);
????????public?event?StateChangedEventHandler?StateChanged;
????????public?event?IdleEventHandler?Idle;
????????public?event?ErrorEventHandler?Error;
????}
在處理進度變化的時候,我使用了一個抽象的接口 IProgress,這個抽象接口提供外部對進度的查詢功能,接口定義如下:
????/**////?<summary>
????///?反映進度的變化的接口
????///?</summary>
????public?interface?IProgress
????{
????????int?Total{get;}
????????int?CurrentProgress{get;}
????????string?Description{get;}
????}
在具體實現的時候,可以看我的 ProgressMoniter 的代碼,這個是利用一個單獨的線程來定期輪詢 IProgress 接口進度變化,然后產生事件通知,是最好的說明例子,如果有人想修改成非輪詢的方式,也很容易。
????public?class?ProgressMoniter?:?AsyncWorker
????{
????????public?delegate?void?ProgressEventHandler(string?text,?int?percent);
????????public?event?ProgressEventHandler?Progress;
????????IProgress?m_Progress;
????????private?bool?m_Exit;
????????public?bool?Exit?{?get?{?return?m_Exit;?}?set?{?m_Exit?=?value;?}?}
????????public?ProgressMoniter(IProgress?progress)?:?base(false)
????????{
????????????m_Progress?=?progress;
????????????m_Exit?=?false;
????????}
????????protected?override?void?DoWork()
????????{
????????????while(?!m_Exit?)
????????????{
????????????????lock(m_Progress)
????????????????????OnProgress(m_Progress.Description,?m_Progress.Total,?m_Progress.CurrentProgress);
????????????????Thread.Sleep(200);
????????????}
????????}
????????private?void?OnProgress(string?description,?int?total,?int?progress)
????????{
????????????if(?Progress?!=?null?)
????????????????Progress.BeginInvoke(description,?(int)((long)progress?*?100?/?(long)total),?null,?null);
????????}
????}
我在處理過程中使用了一個封裝了異步線程處理的一個抽象類,這個抽象類實現了異步處理的 Start,Abort, Pause 和 Resume 接口,大家用它來實現異步處理的時候,就可以象玩秒表一樣隨意地控制這些處理過程了。完整的代碼如下:
????public?abstract?class?AsyncWorker
????{
????????public?enum?WorkState{Ready,?Working,?Pause,Resume,Aborted,?Done,?Error}
????????private?WorkState?m_State;
????????private?bool?m_Wait;
????????private?Thread?m_Thread;
????????protected?AsyncWorker(bool?wait)
????????{
????????????m_State?=?WorkState.Ready;
????????????m_Wait?=?wait;
????????????m_Thread?=?new?Thread(new?ThreadStart(Work));
????????}
????????public?void?Start()
????????{
????????????OnStateChangedSync(WorkState.Ready);
????????????m_Thread.Start();
????????????while(?m_Wait?&&?m_Thread.IsAlive?)
????????????{
????????????????OnIdle();
????????????????Thread.Sleep(200);
????????????}
????????}
????????public?void?Pause()
????????{
????????????if(?m_State?==?WorkState.Working)
????????????{
????????????????m_Thread.Suspend();
????????????????m_State?=?WorkState.Pause;
????????????????OnStateChanged(WorkState.Pause);
????????????}
????????}
????????public?void?Resume()
????????{
????????????if(?m_State?==?WorkState.Pause?)
????????????{
????????????????m_State?=?WorkState.Working;
????????????????m_Thread.Resume();
????????????????OnStateChanged(WorkState.Resume);
????????????}
????????}
????????public?void?Abort()
????????{
????????????if(?m_State?==?WorkState.Working?||?m_State?==?WorkState.Pause?)
????????????{
????????????????m_Thread.Abort();
????????????????m_State?=?WorkState.Aborted;
????????????????OnStateChanged(WorkState.Aborted);
????????????}
????????}
????????private?void?Work()
????????{
????????????try
????????????{
????????????????m_State?=?WorkState.Working;
????????????????OnStateChangedSync(WorkState.Working);
????????????????DoWork();
????????????????m_State?=?WorkState.Done;
????????????????OnStateChanged(WorkState.Done);
????????????}
????????????catch?(Exception?e)
????????????{
????????????????m_State?=?WorkState.Error;
????????????????OnError(e);
????????????????OnStateChanged(WorkState.Error);
????????????}
????????}
????????protected?abstract?void?DoWork();
????????private?void?OnStateChangedSync(WorkState?state)
????????{
????????????if(?StateChanged?!=?null?)
????????????????StateChanged(this,?state);
????????}
????????private?void?OnStateChanged(WorkState?state)
????????{
????????????if(?StateChanged?!=?null?)
????????????????StateChanged.BeginInvoke(this,?state,?null,?null);
????????}
????????protected?void?OnIdle()
????????{
????????????if(?Idle?!=?null?)
????????????{
????????????????lock(this)????????//?有可能會很高頻率調用
????????????????????Idle(this);
????????????}
????????}
????????protected?void?OnError(Exception?e)
????????{
????????????if(?Error?!=?null?)
????????????????Error.BeginInvoke(this,?e,?null,?null);
????????}
????????public?delegate?void?StateChangedEventHandler(AsyncWorker?sender,?WorkState?state);
????????public?delegate?void?IdleEventHandler(AsyncWorker?sender);
????????public?delegate?void?ErrorEventHandler(AsyncWorker?sender,?Exception?e);
????????public?event?StateChangedEventHandler?StateChanged;
????????public?event?IdleEventHandler?Idle;
????????public?event?ErrorEventHandler?Error;
????}
在處理進度變化的時候,我使用了一個抽象的接口 IProgress,這個抽象接口提供外部對進度的查詢功能,接口定義如下:
????/**////?<summary>
????///?反映進度的變化的接口
????///?</summary>
????public?interface?IProgress
????{
????????int?Total{get;}
????????int?CurrentProgress{get;}
????????string?Description{get;}
????}
在具體實現的時候,可以看我的 ProgressMoniter 的代碼,這個是利用一個單獨的線程來定期輪詢 IProgress 接口進度變化,然后產生事件通知,是最好的說明例子,如果有人想修改成非輪詢的方式,也很容易。
????public?class?ProgressMoniter?:?AsyncWorker
????{
????????public?delegate?void?ProgressEventHandler(string?text,?int?percent);
????????public?event?ProgressEventHandler?Progress;
????????IProgress?m_Progress;
????????private?bool?m_Exit;
????????public?bool?Exit?{?get?{?return?m_Exit;?}?set?{?m_Exit?=?value;?}?}
????????public?ProgressMoniter(IProgress?progress)?:?base(false)
????????{
????????????m_Progress?=?progress;
????????????m_Exit?=?false;
????????}
????????protected?override?void?DoWork()
????????{
????????????while(?!m_Exit?)
????????????{
????????????????lock(m_Progress)
????????????????????OnProgress(m_Progress.Description,?m_Progress.Total,?m_Progress.CurrentProgress);
????????????????Thread.Sleep(200);
????????????}
????????}
????????private?void?OnProgress(string?description,?int?total,?int?progress)
????????{
????????????if(?Progress?!=?null?)
????????????????Progress.BeginInvoke(description,?(int)((long)progress?*?100?/?(long)total),?null,?null);
????????}
????}
總結
以上是生活随笔為你收集整理的通用的异步处理类和进度通知类及其示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编辑器FreeTextBox升级至3.0
- 下一篇: asp.net开发 网络硬盘[转贴+删节