Registrieren eines COM-Rückrufs

Anstatt Änderungen am status eines Auftrags abzufragen, können Sie sich registrieren, um eine Benachrichtigung zu erhalten, wenn sich die status des Auftrags ändert. Um Benachrichtigungen zu erhalten, müssen Sie die IBackgroundCopyCallback2-Schnittstelle implementieren. Die -Schnittstelle enthält die folgenden Methoden, die BITS je nach Registrierung aufruft:

Ein Beispiel, das die IBackgroundCopyCallback2-Schnittstelle implementiert, finden Sie im Beispielcode im Thema IBackgroundCopyCallback-Schnittstelle .

Die IBackgroundCopyCallback2-Schnittstelle stellt eine Benachrichtigung bereit, wenn eine Datei übertragen wird. In der Regel verwenden Sie diese Methode, um die Datei zu überprüfen, sodass die Datei für Peers zum Herunterladen verfügbar ist. Andernfalls ist die Datei erst für Peers verfügbar, wenn Sie die IBackgroundCopyJob::Complete-Methode aufrufen. Rufen Sie zum Überprüfen der Datei die IBackgroundCopyFile3::SetValidationState-Methode auf.

Es gibt zwei Methoden zum Registrieren eines COM-Rückrufs: Registrieren eines Rückrufobjekts oder Registrieren einer Rückrufklassen-ID. Die Verwendung eines Rückrufobjekts ist einfacher und geringerer Aufwand. Die Verwendung einer Rückruf-CLSID ist zuverlässiger, aber komplizierter. Sie können sowohl als auch keines von beiden registrieren. BITS verwendet ein Rückrufobjekt, sofern vorhanden und weiterhin aufgerufen werden kann, und führt einen Fallback auf die Instanziierung eines neuen Objekts basierend auf einer bereitgestellten Klassen-ID aus, wenn dies fehlschlägt.

Registrieren eines Rückrufobjekts

Um Ihre Implementierung bei BITS zu registrieren, rufen Sie die IBackgroundCopyJob::SetNotifyInterface-Methode auf. Um anzugeben, welche Methoden BITS aufruft, rufen Sie die IBackgroundCopyJob::SetNotifyFlags-Methodeauf.

Die Benachrichtigungsschnittstelle wird ungültig, wenn Ihre Anwendung beendet wird. BITS speichert die Benachrichtigungsschnittstelle nicht. Daher sollte der Initialisierungsprozess Ihrer Anwendung vorhandene Aufträge registrieren, für die Sie eine Benachrichtigung erhalten möchten. Wenn Sie Status- und Statusinformationen erfassen müssen, die seit der letzten Ausführung der Anwendung aufgetreten sind, rufen Sie während der Anwendungsinitialisierung Status- und Statusinformationen ab.

Vor dem Beenden sollte Ihre Anwendung den Rückrufschnittstellenzeiger (SetNotifyInterface(NULL)) löschen. Es ist effizienter, den Rückrufzeiger zu löschen, als bits erkennen zu lassen, dass er nicht mehr gültig ist.

Wenn mehr als eine Anwendung die SetNotifyInterface-Methode aufruft, um die Benachrichtigungsschnittstelle für den Auftrag festzulegen, ist die letzte Anwendung, die die SetNotifyInterface-Methode aufruft, die Benachrichtigungen empfängt. Die anderen Anwendungen erhalten keine Benachrichtigungen.

Das folgende Beispiel zeigt, wie Sie sich für Benachrichtigungen registrieren. Im Beispiel wird davon ausgegangen, dass der IBackgroundCopyJob-Schnittstellenzeiger gültig ist. Ausführliche Informationen zur CNotifyInterface-Beispielklasse, die im folgenden Beispiel verwendet wird, finden Sie unter der IBackgroundCopyCallback-Schnittstelle .

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.
    }
}

Registrieren einer Rückruf-CLSID

Um eine Rückruf-CLSID bei BITS zu registrieren, rufen Sie die IBackgroundCopyJob5::SetProperty-Methode mit dem BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId auf. Um anzugeben, welche Methoden BITS aufruft, rufen Sie die IBackgroundCopyJob::SetNotifyFlags-Methode auf.

Sie müssen sicherstellen, dass die CLSID-Benachrichtigung bei einem out-of-process COM-Server registriert ist, bevor Sie die CLSID mit einem BITS-Auftrag registrieren. Die Implementierung eines COM-Servers ist erheblich komplizierter als das Definieren und Übergeben eines Rückrufobjekts, bietet jedoch mehrere wichtige Vorteile. Ein COM-Server ermöglicht ES BITS, die Zuordnung zwischen einem BITS-Auftrag und dem Code Ihrer Anwendung über Systemneustarts hinweg und für große oder langlebige Aufträge beizubehalten. Mit einem COM-Server kann Ihre Anwendung auch vollständig heruntergefahren werden, während BITS weiterhin Übertragungen im Hintergrund ausführt, was die Akku-, CPU- und Arbeitsspeicherauslastung des Systems verbessern kann.

Um eine Benachrichtigung bereitzustellen, die Sie für den Empfang registriert haben, versucht BITS zunächst, die entsprechende Methode eines vorhandenen Rückrufobjekts aufzurufen, das Sie möglicherweise angefügt haben. Wenn kein Objekt vorhanden ist oder dieses vorhandene Objekt getrennt wurde (in der Regel aufgrund der Beendigung Ihrer Anwendung), ruft BITS CoCreateInstance mithilfe der Benachrichtigungs-CLSID auf, um ein neues Rückrufobjekt zu instanziieren, und verwendet dieses Objekt für alle weiteren Rückrufe, bis es getrennt wird oder durch einen neuen Aufruf von IBackgroundCopyJob ersetzt wird: SetNotifyInterface.

Im Gegensatz zu Rückrufobjekten wird die Rückruf-CLSID zusammen mit den entsprechenden BITS-Aufträgen beibehalten, wenn der BITS-Dienst oder das System heruntergefahren und neu gestartet wird. Ihre Anwendung kann alle zuvor festgelegten Benachrichtigungs-CLSID vor dem Beenden (oder zu einem anderen Zeitpunkt) löschen, indem sie eine neue Benachrichtigungs-CLSID von GUID_NULL übergibt, aber Ihre Anwendung zieht es vor, die Benachrichtigung CLSID registriert zu lassen, wenn Ihre Anwendung registriert hat, um sie als Reaktion auf CoCreateInstance-Anforderungen für Ihre CLSID zu starten. Beachten Sie, dass, wenn mehrere Anwendungen festlegen, dass die BITS_JOB_PROPERTY_NOTIFICATION_CLSID-Eigenschaft aufruft, die letzte FESTZULEGENDE CLSID diejenige ist, die BITS zum Instanziieren von Rückrufobjekten verwendet. Die anderen CLSIDs werden nicht instanziiert. Wenn eine Anwendung eine CLSID registriert und eine andere ein Rückrufobjekt registriert, gelten die üblichen Regeln für das Rückrufobjekt, das Vorrang hat, und die CLSID wird nur verwendet, wenn das Rückrufobjekt gelöscht oder getrennt wird.

Das folgende Beispiel zeigt, wie Sie sich für CLSID-Benachrichtigungen registrieren. Im Beispiel wird davon ausgegangen, dass der IBackgroundCopyJob5-Schnittstellenzeiger gültig ist und dass Ihre Anwendung bereits als out-of-process-COM-Server registriert ist, der die CNotifyInterface-Klasse implementiert. Ausführliche Informationen zur CNotifyInterface-Beispielklasse, die im folgenden Beispiel verwendet wird, finden Sie unter der IBackgroundCopyCallback-Schnittstelle .

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. 
}