Share via


Inscription d’un rappel COM

Au lieu d’interroger les modifications apportées au status d’un travail, vous pouvez vous inscrire pour recevoir une notification lorsque le status du travail change. Pour recevoir une notification, vous devez implémenter l’interface IBackgroundCopyCallback2 . L’interface contient les méthodes suivantes que BITS appelle, en fonction de votre inscription :

Pour obtenir un exemple qui implémente l’interface IBackgroundCopyCallback2 , consultez l’exemple de code dans la rubrique interface IBackgroundCopyCallback .

L’interface IBackgroundCopyCallback2 fournit une notification lorsqu’un fichier est transféré. En règle générale, vous utilisez cette méthode pour valider le fichier, afin que le fichier soit disponible pour que les homologues puissent le télécharger ; sinon, le fichier n’est pas disponible pour les homologues tant que vous n’appelez pas la méthode IBackgroundCopyJob::Complete . Pour valider le fichier, appelez la méthode IBackgroundCopyFile3::SetValidationState .

Il existe deux méthodes pour inscrire un rappel COM : l’inscription d’un objet de rappel ou l’inscription d’un ID de classe de rappel. L’utilisation d’un objet de rappel est plus simple et réduit la surcharge ; l’utilisation d’un CLSID de rappel est plus fiable, mais plus compliquée. Vous pouvez inscrire l’un ou l’autre, les deux ou ni l’un ni l’autre : BITS utilise un objet de rappel s’il en existe un et peut toujours être appelé, et revient à instancier un nouvel objet en fonction d’un ID de classe fourni en cas d’échec.

Inscription d’un objet Callback

Pour inscrire votre implémentation auprès de BITS, appelez la méthode IBackgroundCopyJob::SetNotifyInterface . Pour spécifier les méthodes d’appels BITS, appelez la méthode IBackgroundCopyJob::SetNotifyFlags.

L’interface de notification devient non valide lorsque votre application se termine ; BITS ne conserve pas l’interface de notification. Par conséquent, le processus d’initialisation de votre application doit inscrire les travaux existants pour lesquels vous souhaitez recevoir une notification. Si vous devez capturer les informations d’état et de progression qui se sont produites depuis la dernière exécution de votre application, interrogez les informations d’état et de progression pendant l’initialisation de l’application.

Avant de quitter, votre application doit effacer le pointeur d’interface de rappel (SetNotifyInterface(NULL)). Il est plus efficace d’effacer le pointeur de rappel que de laisser BITS découvrir qu’il n’est plus valide.

Notez que si plusieurs applications appellent la méthode SetNotifyInterface pour définir l’interface de notification du travail, la dernière application à appeler la méthode SetNotifyInterface est celle qui recevra des notifications. Les autres applications ne recevront pas de notifications.

L’exemple suivant montre comment s’inscrire aux notifications. L’exemple suppose que le pointeur d’interface IBackgroundCopyJob est valide. Pour plus d’informations sur l’exemple de classe CNotifyInterface utilisée dans l’exemple suivant, consultez l’interface 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.
    }
}

Inscription d’un CLSID de rappel

Pour inscrire un CLSID de rappel avec BITS, appelez la méthode IBackgroundCopyJob5::SetProperty avec l’BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId. Pour spécifier les méthodes d’appels BITS, appelez la méthode IBackgroundCopyJob::SetNotifyFlags .

Vous devez vous assurer que le CLSID de notification est inscrit auprès d’un serveur COM hors processus avant d’inscrire le CLSID avec un travail BITS. L’implémentation d’un serveur COM est beaucoup plus compliquée que la définition et la transmission d’un objet de rappel, mais offre plusieurs avantages importants. Un serveur COM permet à BITS de maintenir l’association entre un travail BITS et le code de votre application entre les redémarrages du système et pour les travaux volumineux ou de longue durée. Un serveur COM permet également à votre application de s’arrêter complètement pendant que BITS continue d’exécuter les transferts en arrière-plan, ce qui peut améliorer l’utilisation de la batterie, du processeur et de la mémoire du système.

Pour fournir une notification que vous avez inscrite pour recevoir, BITS tente d’abord d’appeler la méthode correspondante de tout objet de rappel existant que vous avez peut-être attaché. S’il n’existe aucun objet ou si cet objet existant est déconnecté (généralement à la suite de la fin de votre application), BITS appelle CoCreateInstance à l’aide du CLSID de notification pour instancier un nouvel objet de rappel, et utilise cet objet pour tous les rappels supplémentaires jusqu’à ce qu’il soit déconnecté ou qu’il soit remplacé par un nouvel appel à IBackgroundCopyJob :: SetNotifyInterface.

Contrairement aux objets de rappel, le CLSID de rappel est conservé en même temps que leurs travaux BITS correspondants si le service BITS ou le système sont arrêtés et redémarrés. Votre application peut effacer tout CLSID de notification défini précédemment avant de quitter (ou à tout autre moment) en transmettant un nouveau CLSID de notification de GUID_NULL, mais votre application peut préférer laisser le CLSID de notification inscrit si votre application s’est inscrite pour que COM démarre en réponse aux demandes CoCreateInstance pour votre CLSID. Notez que si plusieurs applications définissent la propriété BITS_JOB_PROPERTY_NOTIFICATION_CLSID , le dernier CLSID à définir est celui que BITS utilisera pour instancier des objets de rappel . Les autres CLSID ne seront pas instanciés. De même, si une application inscrit un CLSID et une autre inscrit un objet de rappel, les règles habituelles pour l’objet de rappel prioritaire s’appliquent et le CLSID ne sera utilisé que si l’objet de rappel est effacé ou se déconnecte.

L’exemple suivant montre comment s’inscrire aux notifications CLSID. L’exemple suppose que le pointeur d’interface IBackgroundCopyJob5 est valide et que votre application est déjà inscrite en tant que serveur COM hors processus qui implémente la classe CNotifyInterface. Pour plus d’informations sur l’exemple de classe CNotifyInterface utilisée dans l’exemple suivant, consultez l’interface 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. 
}