超实用“伪同步”设计代码,用处多多

来源:互联网 发布:caffe 中文教程 编辑:程序博客网 时间:2024/04/28 19:57

想想做软件的各位,肯定会碰到这种情况:
一个任务需要多个步骤完成,且中间步骤又可能是个异步的操作,这样要完成整个任务假如采用异步方式的话那代码关系很复杂。举个例子,使用http下载一个文件,当要支持另存这个文件时,首先要弹出一个路径选择的对话框,选择好以后继续进行后续数据的写入。很明显,使用同步代码来完成这样的任务看起来会简单非常多,而且代码逻辑也更清晰明了。下面的代码就是为这个设计的,非常好用、实用~

备注(使用说明):
1. 适合线程内同步等待(不会挂起线程,线程还是活的)
2. 需要同步等待的地方调用:TInt CFakeSyncAO::NewL(TInt aTimeout)
   @aTimeout: 等待超时时间(微秒)
   @ret:结束原因(一般0表示成功,其他表示失败)
3. 在其他地方完成后调用:void CFakeSyncAO ::StopSyncWait(TInt aError)
   @aError:结束同步等待,结束原因

头文件:FakeSyncAO.h

  1. /*
  2. ============================================================================
  3. Name        : FakeSyncAO.h
  4. Author          : Alex
  5. Version         : 1.0
  6. Copyright   : Your copyright notice
  7. Description : CTraceLog declaration
  8. ============================================================================
  9. */
  10. #ifndef __FAKESYNCAO_H__
  11. #define __FAKESYNCAO_H__
  12. #include <e32base.h>
  13. class CPeriodic;
  14. class CFakeSyncAO : public CActive            
  15. {          
  16. public:               
  17.         static TInt NewL(TInt aTimeout=0);               
  18.         static void StopSyncWait(TInt aError=0);
  19.         ~CFakeSyncAO();               
  20. protected:                       
  21.         void DoCancel();               
  22.         void RunL();       
  23.        
  24. private:       
  25.         static CFakeSyncAO* NewLC(TInt aTimeout);       
  26.         CFakeSyncAO(TInt aTimeout);
  27.         void ConstructL();
  28.         void StartSyncWait();
  29.         static TInt OnTimeout(TAny* aObj);
  30. private:       
  31.         CActiveSchedulerWait iWait;
  32.         CPeriodic*        iTimeout;
  33.         TInt         iTimeDelay;
  34. };
  35. #endif
复制代码
源文件:fakeSyncAO.cpp
  1. #include "fakeSyncAO.h"
  2. CFakeSyncAO* g_SyncWaitAo = NULL;
  3. TInt CFakeSyncAO::NewL(TInt aTimeout)   
  4. {   
  5.         TInt ret = 0;
  6.         g_SyncWaitAo = NewLC(aTimeout);   
  7.         g_SyncWaitAo->StartSyncWait();
  8.         ret = g_SyncWaitAo->iStatus.Int();
  9.         CleanupStack::PopAndDestroy();  
  10.         g_SyncWaitAo = NULL;
  11.         //signal coming, delete self
  12.         return ret;   
  13. }
  14. void CFakeSyncAO::StopSyncWait(TInt aError)
  15. {
  16.         if(g_SyncWaitAo!=NULL && g_SyncWaitAo->IsActive())
  17.         {
  18.                 TRequestStatus* status = &(g_SyncWaitAo->iStatus);
  19.                 User::RequestComplete(status,aError);
  20.         }
  21. }
  22. CFakeSyncAO* CFakeSyncAO::NewLC(TInt aTimeout)   
  23. {   
  24.         CFakeSyncAO* self = new (ELeave) CFakeSyncAO(aTimeout);
  25.         CleanupStack::PushL(self);   
  26.         self->ConstructL();   
  27.         return self;   
  28. }  
  29. CFakeSyncAO::CFakeSyncAO(TInt aTimeout)
  30. :CActive(CActive::EPriorityLow)
  31. {
  32.         iTimeDelay = aTimeout;
  33. }
  34. CFakeSyncAO::~CFakeSyncAO()
  35. {       
  36.         Cancel();
  37. }
  38. void CFakeSyncAO::ConstructL()
  39. {       
  40.         CActiveScheduler::Add(this);
  41. }
  42. void CFakeSyncAO::StartSyncWait()
  43. {       
  44.         if(iTimeDelay != 0)
  45.         {
  46.                 iTimeout = CPeriodic::New(CActive::EPriorityStandard);
  47.                 iTimeout->Start(iTimeDelay,KMaxTInt32,TCallBack(CFakeSyncAO::OnTimeout,this));
  48.         }
  49.         SetActive();
  50.         iStatus = KRequestPending;
  51.         iWait.Start();
  52. }
  53. void CFakeSyncAO::DoCancel()
  54. {       
  55. }  
  56. TInt CFakeSyncAO::OnTimeout(TAny* aObj)
  57. {
  58.         CFakeSyncAO* obj = (CFakeSyncAO*)aObj;
  59.         if(obj->iWait.IsStarted())
  60.         {
  61.                 obj->iWait.AsyncStop();
  62.         }
  63.         return 0;
  64. }
  65. void CFakeSyncAO::RunL()
  66. {       
  67.         if(iWait.IsStarted())
  68.         {
  69.                 iWait.AsyncStop();
  70.         }
  71. }

原创粉丝点击