ADO: синхронное и ассинхронное выполение команд
От: Stain  
Дата: 21.11.02 07:37
Оценка:
Почему ассинхронное выполнение команд происходит в 8 раз медленнее синхронного...

Ассинхронное выполнение происходит с помощью ADO events...

Данные берутся из очереди куда они кладутся по таймеры в определенные промежутки времени....

Выполняются 5 команд, которые вставляют данные в 5 разных таблиц....

Вот код:


        DWORD   dwConnEvt;

        ADODB::_ConnectionPtr pConnection;
        ADODB::_CommandPtr pCmd[MAX_COMMAND];

        IConnectionPointContainer   *pCPC = NULL;
        IConnectionPoint *pCP = NULL;
        IUnknown *pUnk = NULL;
   

        TESTHR(pConnection.CreateInstance( __uuidof ( ADODB::Connection ) ));

        TESTHR(pConnection->QueryInterface(__uuidof(IConnectionPointContainer),(void **)&pCPC));
        TESTHR(pCPC->FindConnectionPoint(__uuidof(ADODB::ConnectionEvents), &pCP));
        TESTHR(pCPC->Release());

        
        m_pConnEvent = new CConnEvent(m_nThreadId,this);
        TESTHR(m_pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk));
        TESTHR(pCP->Advise(pUnk, &dwConnEvt));
        TESTHR(pCP->Release());


        pConnection->ConnectionString = _bstr_t("Provider=sqloledb;Data Source=PROBA;DATABASE=tempdb;UID=sa;PWD=;");
        pConnection->ConnectionTimeout = 15;
        pConnection->Mode = ADODB::adModeReadWrite;
        pConnection->Open("", "", "", ADODB::adConnectUnspecified );            
        pConnection->CommandTimeout = 30;


        for(i = 0 ; i < MAX_COMMAND ; i++)
        {
            TESTHR(pCmd[i].CreateInstance(__uuidof(ADODB::Command)));
            pCmd[i]->ActiveConnection = pConnection;
            pCmd[i]->CommandTimeout = 15;

            CString str;
            str.Format("INSERT INTO TRADE_%d (EventID,FinToolID,SourceID,EventTime) VALUES(?,?,?,'%s')",i,COleDateTime::GetCurrentTime().Format());
            pCmd[i]->CommandText = _bstr_t(str);
            pCmd[i]->PutPrepared(true);
            pCmd[i]->Parameters->Refresh();
        }

        m_pConnEvent->SetPointers(MAX_COMMAND,(long*)pCmd);


...............

                if(((CButton*)GetDlgItem(IDC_RADIO_SYNC))->GetCheck())
                {
                    while(1)
                    {
                        long cAllCount = 0;
                        for(int i = 0 ; i < MAX_COMMAND ; i++)
                        {
                            long cCount = 0;
                            {
                                CLock Lock( m_csList + i );
                                cCount = m_list[i].size();
                            }
                            cAllCount += cCount;

                            if(cCount)
                            {
                                    int num;
                                    {
                                        CLock Lock( m_csList + i );
                                        num = *m_list[i].begin();
                                        m_list[i].pop_front();
                                    }
                                                    
                                    _variant_t param;
                                    param.vt = VT_I4;
                                    
                                    _variant_t Index;
                                    Index.vt = VT_I2;

                                    Index.iVal = 0;
                                    param.iVal = num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    Index.iVal = 1;
                                    param.iVal = 2 * num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    Index.iVal = 2;
                                    param.iVal = 4 * num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    pCmd[i]->Execute(NULL,NULL,0);
                            }
                        }

                    }
                }
                else
                {
                    while(1)
                    {
                        long cAllCount = 0;
                        if( MsgWaitForMultipleObjects(0, NULL, FALSE, 0, QS_ALLINPUT) == WAIT_TIMEOUT )
                        {
                            for(int i = 0 ; i < MAX_COMMAND ; i++)
                            {
                                long cCount = 0;
                                {
                                    CLock Lock( m_csList + i );
                                    cCount = m_list[i].size();
                                }
                                cAllCount += cCount;

                                if(cCount && IsCommandDone(i))
                                {
                                    int num;
                                    {
                                        CLock Lock( m_csList + i );
                                        num = *m_list[i].begin();
                                        m_list[i].pop_front();
                                    }
                                                    
                                    SetCommandDone( i,false );

                                    _variant_t param;
                                    param.vt = VT_I4;
                                    
                                    _variant_t Index;
                                    Index.vt = VT_I2;

                                    Index.iVal = 0;
                                    param.iVal = num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    Index.iVal = 1;
                                    param.iVal = 2 * num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    Index.iVal = 2;
                                    param.iVal = 4 * num;
                                    pCmd[i]->GetParameters()->GetItem(Index)->PutValue(param);

                                    pCmd[i]->Execute(NULL,NULL,ADODB::adAsyncExecute);
                                }
                            }
                        }
                        else
                        {
                            // There is one or more window message available. Dispatch them
                            while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
                            {
//                                TranslateMessage(&msg);
                                DispatchMessage(&msg);
                            }
                        }

                    }
                }

............................


TESTHR(pConnection->QueryInterface(__uuidof(IConnectionPointContainer),(void **) &pCPC));
TESTHR(pCPC->FindConnectionPoint(__uuidof(ADODB::ConnectionEvents), &pCP));
TESTHR(pCPC->Release());
TESTHR(pCP->Unadvise( dwConnEvt ));
TESTHR(pCP->Release());
TESTHR(pConnection->Close());

....................

STDMETHODIMP CAsyncADODlg::CConnEvent::raw_ExecuteComplete( 
                                    LONG RecordsAffected,
                                    struct ADODB::Error *pError,
                                    ADODB::EventStatusEnum *adStatus,
                                    struct ADODB::_Command *pCommand,
                                    struct ADODB::_Recordset *pRecordset,
                                    struct ADODB::_Connection *pConnection
                            )
{
    if(*adStatus == ADODB::adStatusOK)
    {
        for(int i = 0; i < m_cCommand; i++)
        {
            if((long)pCommand == m_pCommand[i])
            {
                m_ptr->SetCommandDone(i,true);
                TRACE2("CommandID=%d, ThreadID=%d\n", i, ::GetCurrentThreadId() );
                break;
            }
        }
    }
    else
    {
        CString str;
        str.Format("Error #%d\n %s\n (Source: %s)\n (SQL State: %s)\n (NativeError: %d)\n", 
                    pError->Number,(LPCSTR)pError->Description,(LPCSTR)pError->Source,
                    (LPCSTR)pError->SQLState,(LPCSTR)pError->NativeError);

        ::MessageBox(NULL,str,"Error",MB_OK);
    }

    return S_OK;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.