Compartir a través de


Registro de una devolución de llamada COM

En lugar de sondear los cambios en el estado de un trabajo, puede registrarse para recibir una notificación cuando cambie el estado del trabajo. Para recibir notificaciones, debe implementar la interfaz IBackgroundCopyCallback2 . La interfaz contiene los métodos siguientes que BITS llama, en función del registro:

Para obtener un ejemplo que implementa la interfaz IBackgroundCopyCallback2 , vea el código de ejemplo en el tema de la interfaz IBackgroundCopyCallback .

La interfaz IBackgroundCopyCallback2 proporciona una notificación cuando se transfiere un archivo. Normalmente, se usa este método para validar el archivo, de modo que el archivo esté disponible para que los elementos del mismo nivel se descarguen; de lo contrario, el archivo no está disponible para elementos del mismo nivel hasta que se llama al método IBackgroundCopyJob::Complete . Para validar el archivo, llame al método IBackgroundCopyFile3::SetValidationState .

Hay dos métodos para registrar una devolución de llamada COM: registrar un objeto de devolución de llamada o registrar un identificador de clase de devolución de llamada. El uso de un objeto de devolución de llamada es más sencillo y menor sobrecarga; el uso de clSID de devolución de llamada es más confiable, pero más complicado. Puede registrar o ninguno de ellos: BITS usará un objeto de devolución de llamada si existe y se puede seguir llamando, y revertirá a la creación de instancias de un nuevo objeto en función de un identificador de clase proporcionado si se produce un error.

Registro de un objeto de devolución de llamada

Para registrar la implementación con BITS, llame al método IBackgroundCopyJob::SetNotifyInterface . Para especificar qué métodos llama a BITS, llame al método IBackgroundCopyJob::SetNotifyFlags.

La interfaz de notificación deja de ser válida cuando la aplicación finaliza; BITS no conserva la interfaz de notificación. Como resultado, el proceso de inicialización de la aplicación debe registrar los trabajos existentes para los que desea recibir la notificación. Si necesita capturar información de estado y progreso que se produjo desde la última vez que se ejecutó la aplicación, sondee la información de estado y progreso durante la inicialización de la aplicación.

Antes de salir, la aplicación debe borrar el puntero de la interfaz de devolución de llamada (SetNotifyInterface(NULL)). Es más eficaz borrar el puntero de devolución de llamada que permitir que BITS detecte que ya no es válido.

Tenga en cuenta que si más de una aplicación llama al método SetNotifyInterface para establecer la interfaz de notificación para el trabajo, la última aplicación para llamar al método SetNotifyInterface es la que recibirá notificaciones; las demás aplicaciones no recibirán notificaciones.

En el ejemplo siguiente se muestra cómo registrarse para recibir notificaciones. En el ejemplo se supone que el puntero de interfaz IBackgroundCopyJob es válido. Para obtener más información sobre la clase de ejemplo CNotifyInterface usada en el ejemplo siguiente, vea la interfaz 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.
    }
}

Registro de un CLSID de devolución de llamada

Para registrar un CLSID de devolución de llamada con BITS, llame al método IBackgroundCopyJob5::SetProperty con el BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId. Para especificar qué métodos llama a BITS, llame al método IBackgroundCopyJob::SetNotifyFlags .

Debe asegurarse de que el CLSID de notificación está registrado en un servidor COM fuera de proceso antes de registrar el CLSID con un trabajo de BITS. La implementación de un servidor COM es significativamente más complicada que definir y pasar un objeto de devolución de llamada, pero ofrece varias ventajas importantes. Un servidor COM permite a BITS mantener la asociación entre un trabajo de BITS y el código de la aplicación entre reinicios del sistema y para trabajos de larga duración o de gran tamaño. Un servidor COM también permite que la aplicación se apague completamente mientras BITS sigue ejecutando transferencias en segundo plano, lo que puede mejorar el uso de batería, CPU y memoria del sistema.

Para proporcionar una notificación que ha registrado para recibir, BITS primero intenta llamar al método correspondiente de cualquier objeto de devolución de llamada existente que haya asociado. Si no hay ningún objeto existente o si ese objeto existente se ha desconectado (normalmente como resultado de la finalización de la aplicación), BITS llamará a CoCreateInstance mediante la notificación CLSID para crear una instancia de un nuevo objeto de devolución de llamada y usará ese objeto para las devoluciones de llamada adicionales hasta que se desconecte o se reemplace por una nueva llamada a IBackgroundCopyJob:: SetNotifyInterface.

A diferencia de los objetos de devolución de llamada, CLSID de devolución de llamada se conservan junto con sus trabajos de BITS correspondientes si el servicio BITS o el sistema se apagan y reinician. La aplicación puede borrar cualquier CLSID de notificación establecida previamente antes de salir (o en cualquier otro momento) pasando un nuevo CLSID de notificación de GUID_NULL, pero la aplicación puede preferir dejar la notificación CLSID registrada si la aplicación se ha registrado para que COM lo inicie en respuesta a las solicitudes coCreateInstance para clSID. Tenga en cuenta que si más de una aplicación establece las llamadas a la propiedad BITS_JOB_PROPERTY_NOTIFICATION_CLSID , el último CLSID que se va a establecer es el que BITS usará para crear instancias de objetos de devolución de llamada, no se crearán instancias de los otros CLSID. Del mismo modo, si una aplicación registra un CLSID y otro registra un objeto de devolución de llamada, se aplican las reglas habituales para el objeto de devolución de llamada que tiene prioridad y el CLSID no se usará a menos que el objeto de devolución de llamada se borre o se desconecte.

En el ejemplo siguiente se muestra cómo registrarse para las notificaciones CLSID. En el ejemplo se supone que el puntero de interfaz IBackgroundCopyJob5 es válido y que la aplicación ya se ha registrado como un servidor COM fuera de proceso que implementa la clase CNotifyInterface. Para obtener más información sobre la clase de ejemplo CNotifyInterface usada en el ejemplo siguiente, vea la interfaz 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. 
}