Share via


Registrazione di un callback COM

Invece di eseguire il polling delle modifiche apportate allo stato di un processo, è possibile registrarsi per ricevere una notifica quando lo stato del processo cambia. Per ricevere la notifica, è necessario implementare l'interfaccia IBackgroundCopyCallback2 . L'interfaccia contiene i metodi seguenti che BITS chiama, a seconda della registrazione:

Per un esempio che implementa l'interfaccia IBackgroundCopyCallback2, vedere il codice di esempio nell'argomento dell'interfaccia IBackgroundCopyCallback.

L'interfaccia IBackgroundCopyCallback2 fornisce una notifica quando viene trasferito un file. In genere, si usa questo metodo per convalidare il file, in modo che il file sia disponibile per il download da parte dei peer; in caso contrario, il file non è disponibile per i peer finché non si chiama il metodo IBackgroundCopyJob::Complete . Per convalidare il file, chiamare il metodo IBackgroundCopyFile3::SetValidationState.

Esistono due metodi per registrare un callback COM: la registrazione di un oggetto callback o la registrazione di un ID classe di callback. L'uso di un oggetto callback è un sovraccarico più semplice e inferiore; l'uso di un CLSID di callback è più affidabile, ma più complicato. È possibile registrare, entrambi o nessuno dei due: BITS userà un oggetto di callback se esistente e può ancora essere chiamato e verrà eseguito il fallback per creare un'istanza di un nuovo oggetto in base a un ID di classe specificato in caso di errore.

Registrazione di un oggetto callback

Per registrare l'implementazione con BITS, chiamare il metodo IBackgroundCopyJob::SetNotifyInterface. Per specificare i metodi chiamati da BITS, chiamare il metodo IBackgroundCopyJob::SetNotifyFlags.

L'interfaccia di notifica non è valida quando l'applicazione termina; BITS non rende persistente l'interfaccia di notifica. Di conseguenza, il processo di inizializzazione dell'applicazione deve registrare i processi esistenti per cui si vuole ricevere una notifica. Se è necessario acquisire informazioni sullo stato e sullo stato che si sono verificate dall'ultima esecuzione dell'applicazione, eseguire il polling delle informazioni sullo stato e sullo stato durante l'inizializzazione dell'applicazione.

Prima di uscire, l'applicazione deve cancellare il puntatore all'interfaccia di callback (SetNotifyInterface(NULL)). È più efficiente cancellare il puntatore di callback rispetto a consentire a BITS di scoprire che non è più valido.

Si noti che se più di un'applicazione chiama il metodo SetNotifyInterface per impostare l'interfaccia di notifica per il processo, l'ultima applicazione a chiamare il metodo SetNotifyInterface è quella che riceverà le notifiche. Le altre applicazioni non riceveranno notifiche.

Nell'esempio seguente viene illustrato come eseguire la registrazione per le notifiche. Nell'esempio si presuppone che il puntatore all'interfaccia IBackgroundCopyJob sia valido. Per informazioni dettagliate sulla classe di esempio CNotifyInterface usata nell'esempio seguente, vedere l'interfaccia IBackgroundCopyCallback .

HRESULT hr;
IBackgroundCopyJob* pJob;
CNotifyInterface *pNotify = new CNotifyInterface();

if (pNotify)
{
    hr = pJob->SetNotifyInterface(pNotify);
    if (SUCCEEDED(hr))
    {
        hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED | 
                                  BG_NOTIFY_JOB_ERROR );
    }
    pNotify->Release();
    pNotify = NULL;

    if (FAILED(hr))
    {
        //Handle error - unable to register callbacks.
    }
}

Registrazione di un CLSID di callback

Per registrare un CALLback CLSID con BITS, chiamare il metodo IBackgroundCopyJob5::SetProperty con il BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId. Per specificare i metodi chiamati da BITS, chiamare il metodo IBackgroundCopyJob::SetNotifyFlags.

È necessario assicurarsi che il CLSID di notifica sia registrato in un server COM out-of-process prima di registrare CLSID con un processo BITS. L'implementazione di un server COM è notevolmente più complessa rispetto alla definizione e al passaggio di un oggetto di callback, ma offre diversi vantaggi importanti. Un server COM consente a BITS di mantenere l'associazione tra un processo BITS e il codice dell'applicazione tra riavvii di sistema e per processi di grandi dimensioni o di lunga durata. Un server COM consente anche all'applicazione di arrestare completamente mentre BITS continua l'esecuzione dei trasferimenti in background, che può migliorare l'utilizzo della batteria, della CPU e della memoria del sistema.

Per fornire una notifica che è stata registrata per la ricezione, BITS tenta prima di tutto di chiamare il metodo corrispondente di qualsiasi oggetto callback esistente associato. Se non è presente alcun oggetto esistente o se l'oggetto esistente è diventato disconnesso (in genere come risultato della terminazione dell'applicazione), BITS chiamerà CoCreateInstance usando il CLSID di notifica per creare un'istanza di un nuovo oggetto callback e userà tale oggetto per eventuali ulteriori callback fino a quando non viene disconnesso o sostituito da una nuova chiamata a IBackgroundCopyJob:: SetNotifyInterface.

A differenza degli oggetti callback, clSID di callback vengono salvati in modo permanente insieme ai processi BITS corrispondenti se il servizio BITS o il sistema vengono arrestati e riavviati. L'applicazione può cancellare qualsiasi CLSID di notifica impostata in precedenza prima dell'uscita (o in qualsiasi altro momento) passando un nuovo CLSID di notifica di GUID_NULL, ma l'applicazione potrebbe preferire lasciare registrata la notifica CLSID se l'applicazione ha registrato l'avvio COM in risposta alle richieste CoCreateInstance per CLSID. Si noti che se più di un'applicazione imposta la chiamata alla proprietà BITS_JOB_PROPERTY_NOTIFICATION_CLSID , l'ultimo CLSID da impostare è quello che BITS userà per creare un'istanza di oggetti callback. Gli altri CLSID non verranno create istanze. Analogamente, se un'applicazione registra un CLSID e un altro registra un oggetto callback, le normali regole per l'oggetto di callback che hanno la precedenza si applicano e il CLSID non verrà utilizzato a meno che l'oggetto di callback non venga cancellato o disconnesso.

Nell'esempio seguente viene illustrato come eseguire la registrazione per le notifiche CLSID. Nell'esempio si presuppone che il puntatore all'interfaccia IBackgroundCopyJob5 sia valido e che l'applicazione sia già registrata come server COM out-of-process che implementa la classe CNotifyInterface. Per informazioni dettagliate sulla classe di esempio CNotifyInterface usata nell'esempio seguente, vedere l'interfaccia IBackgroundCopyCallback .

HRESULT hr; 
IBackgroundCopyJob5* job; 
BITS_JOB_PROPERTY_VALUE propertyValue; 
propertyValue.ClsID = __uuidof(CNotifyInterface); 

hr = job->SetProperty(BITS_JOB_PROPERTY_NOTIFICATION_CLSID, propertyValue); 
if (SUCCEEDED(hr)) 
{ 
    hr = job->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED |  
                             BG_NOTIFY_JOB_ERROR); 
} 

if (FAILED(hr)) 
{ 
    // Handle error - unable to register callbacks. 
}