Udostępnij przez


Rejestrowanie wywołania zwrotnego COM

Zamiast sprawdzania zmiany w stanie zadania, możesz zarejestrować się, aby otrzymywać powiadomienia, kiedy jego stan się zmienia. Aby otrzymywać powiadomienia, należy zaimplementować interfejs IBackgroundCopyCallback2. Interfejs zawiera następujące metody wywoływane przez usługę BITS w zależności od rejestracji:

Przykład, który implementuje interfejs IBackgroundCopyCallback2, znajdziesz w przykładowym kodzie w temacie interfejsu IBackgroundCopyCallback.

Interfejs IBackgroundCopyCallback2 dostarcza powiadomienie po przesłaniu pliku. Zazwyczaj ta metoda służy do sprawdzania poprawności pliku, tak aby plik był dostępny dla elementów równorzędnych do pobrania; w przeciwnym razie plik nie jest dostępny dla elementów równorzędnych, dopóki nie wywołasz metody IBackgroundCopyJob::Complete. Aby zweryfikować plik, wywołaj metodę IBackgroundCopyFile3::SetValidationState.

Istnieją dwie metody rejestrowania wywołania zwrotnego COM: rejestrowanie obiektu wywołania zwrotnego lub rejestrowanie identyfikatora klasy wywołania zwrotnego. Użycie obiektu wywołania zwrotnego jest prostsze i ma niższe koszty; używanie identyfikatora CLSID wywołania zwrotnego jest bardziej niezawodne, ale bardziej skomplikowane. Można zarejestrować jeden, oba lub żaden z nich — usługa BITS będzie korzystać z obiektu wywołania zwrotnego, jeśli taki istnieje i nadal może być wywoływany, a w przypadku niepowodzenia instancjonować nowy obiekt na podstawie podanego identyfikatora klasy.

Rejestrowanie obiektu wywołania zwrotnego

Aby zarejestrować implementację za pomocą usługi BITS, wywołaj metodę IBackgroundCopyJob::SetNotifyInterface. Aby określić, które metody BITS wywołuje, wywołaj metodę IBackgroundCopyJob::SetNotifyFlags.

Interfejs powiadomień staje się nieprawidłowy po zakończeniu działania aplikacji; Usługa BITS nie utrzymuje interfejsu powiadamiania. W związku z tym proces inicjowania aplikacji powinien zarejestrować istniejące zadania, dla których chcesz otrzymywać powiadomienia. Jeśli musisz przechwycić informacje o stanie i postępie, które wystąpiły od czasu ostatniego uruchomienia aplikacji, sprawdź stan i informacje o postępie podczas inicjowania aplikacji.

Przed zakończeniem aplikacja powinna wyczyścić wskaźnik interfejsu wywołania zwrotnego (SetNotifyInterface(NULL)). Bardziej wydajne jest wyczyszczenie wskaźnika wywołania zwrotnego niż pozwolić usłudze BITS wykryć, że nie jest już prawidłowy.

Należy pamiętać, że jeśli więcej niż jedna aplikacja wywołuje metodę SetNotifyInterface w celu ustawienia interfejsu powiadomień dla zadania, ostatnia aplikacja wywołująca metodę SetNotifyInterface jest metodą, która będzie otrzymywać powiadomienia — inne aplikacje nie będą otrzymywać powiadomień.

W poniższym przykładzie pokazano, jak zarejestrować się w celu otrzymywania powiadomień. W przykładzie przyjęto założenie, że wskaźnik interfejsu IBackgroundCopyJob jest prawidłowy. Aby uzyskać szczegółowe informacje na temat przykładowej klasy CNotifyInterface używanej w poniższym przykładzie, zobacz interfejs 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.
    }
}

Rejestrowanie identyfikatora CLSID wywołania zwrotnego

Aby zarejestrować identyfikator CLSID wywołania zwrotnego za pomocą usługi BITS, wywołaj metodę IBackgroundCopyJob5::SetProperty za pomocą BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId. Aby określić, które metody wywołuje BITS, wywołaj metodę IBackgroundCopyJob::SetNotifyFlags.

Należy upewnić się, że identyfikator CLSID powiadomienia jest zarejestrowany na serwerze COM działającym poza procesem, zanim zostanie zarejestrowany z zadaniem usługi BITS. Implementowanie serwera COM jest znacznie bardziej skomplikowane niż definiowanie i przekazywanie obiektu wywołania zwrotnego, ale oferuje kilka ważnych zalet. Serwer COM umożliwia usłudze BITS zachowanie skojarzenia między zadaniem usługi BITS a kodem aplikacji w przypadku ponownych uruchomień systemu oraz w przypadku dużych lub długotrwałych zadań. Serwer COM umożliwia również aplikacji całkowite zamknięcie, podczas gdy usługa BITS kontynuuje wykonywanie transferów w tle, co może poprawić użycie baterii, procesora CPU i pamięci systemu.

Aby dostarczyć powiadomienie, które zarejestrowałeś do otrzymywania, usługa BITS najpierw próbuje wywołać odpowiednią metodę dowolnego istniejącego obiektu wywołania zwrotnego, który mogłeś dołączyć. Jeśli nie ma istniejącego obiektu lub gdy istniejący obiekt został rozłączony (zazwyczaj w wyniku zakończenia aplikacji), usługa BITS wywoła metodę CoCreateInstance przy użyciu identyfikatora CLSID powiadomienia, aby utworzyć nowy obiekt callback i będzie używać tego obiektu dla kolejnych wywołań callback, dopóki nie zostanie odłączony lub zastąpiony przez nowe wywołanie metody IBackgroundCopyJob::SetNotifyInterface.

W przeciwieństwie do obiektów wywołania zwrotnego, identyfikatory CLSID są utrwalane wraz z odpowiednimi zadaniami usługi BITS, jeśli usługa BITS lub system zostanie zamknięty i uruchomiony ponownie. Twoja aplikacja może wyczyścić wszelkie wcześniej ustawione powiadomienia CLSID przed zamknięciem (lub w dowolnym innym momencie działania), przekazując nowe powiadomienie CLSID o wartości GUID_NULL, ale aplikacja może woleć pozostawić powiadomienie CLSID zarejestrowane, jeśli zarejestrowała się, aby COM uruchamiał ją w odpowiedzi na żądania CoCreateInstance dla jej CLSID. Należy pamiętać, że jeśli więcej niż jedna aplikacja ustawia wywołania właściwości BITS_JOB_PROPERTY_NOTIFICATION_CLSID, ostatni identyfikator CLSID, który ma zostać ustawiony, jest tym, który będzie używany przez usługę BITS do tworzenia wystąpień obiektów wywołania zwrotnego — inne identyfikatory CLSID nie zostaną utworzone. Podobnie, jeśli jedna aplikacja rejestruje identyfikator CLSID, a inna rejestruje obiekt wywołania zwrotnego, zwykłe reguły przewagi obiektu wywołania zwrotnego mają zastosowanie, a identyfikator CLSID nie będzie używany, chyba że obiekt wywołania zwrotnego zostanie wyczyszczony lub odłączony.

W poniższym przykładzie pokazano, jak zarejestrować się w celu otrzymywania powiadomień CLSID. W przykładzie przyjęto założenie, że wskaźnik interfejsu IBackgroundCopyJob5 jest prawidłowy i że aplikacja została już zarejestrowana jako serwer COM poza procesem, który implementuje klasę CNotifyInterface. Aby uzyskać szczegółowe informacje na temat przykładowej klasy CNotifyInterface używanej w poniższym przykładzie, zobacz interfejs 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. 
}