ITask实现类的源文件代码
STDMETHODIMP CTask::GetProcessRateOfTask( float *pRate ) { if( !pRate ) return E_INVALIDARG;
*pRate = m_Rate; return S_OK; }
STDMETHODIMP CTask::TerminateTask() { if( !m_hEvent ) return E_FAIL;
return ::SetEvent( m_hEvent ) S_OK : E_FAIL; } |
业务组件的头文件代码
class ATL_NO_VTABLE CExample1Logic : public CComObjectRootEx< CComMultiThreadModel >, public CComCoClass< CExample1Logic, &CLSID_Example1Logic >, public IExample1Logic, public ISetTaskManager { // ATL定义宏 public: DECLARE_PROTECT_FINAL_CONSTRUCT() DECLARE_REGISTRY_RESOURCEID( IDR_EXAMPLE1LOGIC ) BEGIN_COM_MAP( CExample1Logic ) COM_INTERFACE_ENTRY( IExample1Logic ) COM_INTERFACE_ENTRY( ISetTaskManager ) END_COM_MAP()
// 构造、析构 blic: CExample1Logic() : m_Cookie( static_cast< DWORD >( -1 ) ) { ::InitializeCriticalSection( &m_CS ); } ~CExample1Logic();
// 成员变量 protected: DWORD m_Cookie; // ITaskManager的GIT的cookie CRITICAL_SECTION m_CS; // 用于保护m_TaskManagerCookie
// 接口实现 public: // IExample1Logic STDMETHOD(Task1)(); STDMETHOD(Task2)();
// ISetTaskManager STDMETHOD(SetTaskManager)( ITaskManager *pManager ); }; |
业务组件的源文件代码
extern IGlobalInterfaceTable *g_pGIT; CExample1Logic::~CExample1Logic() { ::DeleteCriticalSection( &m_CS );
ATLASSERT( g_pGIT ); // 注销原来的m_Cookie if( m_Cookie != static_cast< DWORD >( -1 ) ) ATLVERIFY( SUCCEEDED( g_pGIT->RevokeInterfaceFromGlobal( m_Cookie ) ) ); }
////////////////////////////IExample1Logic/////////////////////// STDMETHODIMP CExample1Logic::Task1() { // Sleep一段时间以模拟长时间的调用 for( DWORD i = 0; i < 30; i++ ) { Sleep( 300 ); if( ::CoTestCancel() == RPC_E_CALL_CANCELED ) return E_ABORT; } return S_OK; }
STDMETHODIMP CExample1Logic::Task2() { // 通过GIT获得正确的ITaskManager的代理 ITaskNotify *pNotify = NULL; ITaskManager *pManager = NULL;
::EnterCriticalSection( &m_CS ); if( m_Cookie != static_cast< DWORD >( -1 ) ) { ATLASSERT( g_pGIT ); // 不论GetInterfaceFromGlobal是否成功,都必须完成工作 if( SUCCEEDED( g_pGIT->GetInterfaceFromGlobal( m_Cookie, IID_ITaskManager, reinterpret_cast< void** >( &pManager ) ) ) ) pManager->QueryInterface( IID_ITaskNotify, reinterpret_cast< void** >( &pNotify ) ); } ::LeaveCriticalSection( &m_CS );
// 开始任务 static DWORD index = 1; ITask *pTask = NULL; CComObject< CTask > *pTaskObject = NULL; if( FAILED( CComObject< CTask >::CreateInstance( &pTaskObject ) ) ) return E_FAIL; ATLVERIFY( SUCCEEDED( pTaskObject->QueryInterface( IID_ITask, reinterpret_cast< void** >( &pTask ) ) ) ); DWORD cookie = static_cast< DWORD >( -1 ); WCHAR temp[10]; wsprintf( temp, L"任务二%d", index++ );
pTaskObject->m_hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL ); if( pManager && FAILED( pManager->AddTask( temp, pTask, &cookie ) ) ) cookie = static_cast< DWORD >( -1 ); SafeRelease( pManager );
// Sleep各段时间以模拟各步工作的完成 if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 ) goto TERMINATE; pTaskObject->m_Rate = 0.3f; if( pNotify ) pNotify->ProcessRateChange( cookie );
if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 ) goto TERMINATE; pTaskObject->m_Rate = 0.6f; if( pNotify ) pNotify->ProcessRateChange( cookie );
if( ::WaitForSingleObject( pTaskObject->m_hEvent, 4000 ) == WAIT_OBJECT_0 ) goto TERMINATE; pTaskObject->m_Rate = 0.9f; if( pNotify ) pNotify->ProcessRateChange( cookie );
if( pNotify ) { if( cookie != static_cast< DWORD >( -1 ) ) pNotify->TaskOver( cookie ); pNotify->Release(); } pTask->Release();
return S_OK;
TERMINATE: if( pNotify ) { if( cookie != static_cast< DWORD >( -1 ) ) pNotify->TaskOver( cookie ); pNotify->Release(); } pTask->Release();
return RPC_E_CALL_CANCELED; }
/////////////////////////////ISetTaskManager//////////////////////// STDMETHODIMP CExample1Logic::SetTaskManager( ITaskManager *pManager ) { if( !pManager ) return E_POINTER; pManager->AddRef();
ATLASSERT( g_pGIT ); // 注销原来的m_Cookie ::EnterCriticalSection( &m_CS ); if( m_Cookie != static_cast< DWORD >( -1 ) ) ATLVERIFY( SUCCEEDED( g_pGIT->RevokeInterfaceFromGlobal( m_Cookie ) ) );
// 注册新的m_Cookie if( FAILED( g_pGIT->RegisterInterfaceInGlobal( pManager, IID_ITaskManager, &m_Cookie ) ) ) ::InterlockedExchange( reinterpret_cast< LONG* >( &m_Cookie ), static_cast< DWORD >( -1 ) ); ::LeaveCriticalSection( &m_CS );
pManager->Release(); return S_OK; } |
|