註冊 COM 回撥
您可以註冊以接收通知,而不是透過 輪詢 來追蹤作業狀態的變更。 若要接收通知,您必須實作 IBackgroundCopyCallback2 介面。 介面包含 BITS 呼叫的下列方法,視您的註冊而定:
如需實作 IBackgroundCopyCallback2 介面的範例,請參閱 IBackgroundCopyCallback 介面主題中的範例程式代碼。
IBackgroundCopyCallback2 介面會在傳輸檔案時提供通知。 一般而言,您可以使用此方法來驗證檔案,讓檔案可供對等下載;否則,除非您呼叫 IBackgroundCopyJob::Complete 方法,否則檔案無法供對等使用。 若要驗證檔案,請呼叫 IBackgroundCopyFile3::SetValidationState 方法。
註冊 COM 回呼的方法有兩種:註冊回呼物件,或註冊回呼類別標識符。 使用回呼對象比較簡單且額外負荷較低;使用回呼 CLSID 更可靠,但更為複雜。 您可以註冊其中一個、兩個皆註冊或皆不註冊——如果存在可以呼叫的回呼物件,BITS 將使用該回呼物件; 如果這個過程失敗,將會根據提供的類別識別碼來實例化一個新的物件。
註冊回調物件
若要向 BITS 註冊實作,請呼叫 IBackgroundCopyJob::SetNotifyInterface 方法。 若要指定 BITS 呼叫的方法,請呼叫 IBackgroundCopyJob::SetNotifyFlags方法。
當應用程式終止時,通知介面會變成無效;BITS 不會保存通知介面。 因此,應用程式的初始化程式應該註冊您想要接收通知的現有作業。 如果您需要擷取自上次執行應用程式後發生的狀態和進度資訊,請在應用程式初始化期間輪詢狀態和進度資訊。
結束之前,您的應用程式應該清除回呼介面指標 (SetNotifyInterface(NULL)]。 清除回呼指標比讓BITS發現回呼指標不再有效更有效率。
請注意,如果多個應用程式呼叫 SetNotifyInterface 方法來設定作業的通知介面,則呼叫 SetNotifyInterface 方法的最後一個應用程式就是接收通知的方法,其他應用程式將不會收到通知。
下列範例示範如何註冊通知。 此範例假設 IBackgroundCopyJob 介面指標有效。 如需下列範例中使用的 CNotifyInterface 範例類別的詳細資訊,請參閱 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.
}
}
註冊回呼函式 CLSID
若要向 BITS 註冊回呼 CLSID,請使用 IBackgroundCopyJob5::SetProperty 方法搭配 BITS_JOB_PROPERTY_NOTIFICATION_CLSID PropertyId 呼叫。 若要指定 BITS 呼叫的方法,請呼叫 IBackgroundCopyJob::SetNotifyFlags 方法。
在向 BITS 作業註冊 CLSID 之前,您必須確定通知 CLSID 已註冊在外部進程 COM 伺服器。 實作 COM 伺服器 比定義和傳遞回呼物件要複雜得多,但提供數個重要優點。 COM 伺服器可讓 BITS 在系統重新啟動時維持 BITS 作業與應用程式程式代碼之間的關聯,以及針對大型或長時間執行的工作。 COM 伺服器也可讓您的應用程式在 BITS 繼續在背景執行傳輸時完全關閉,這可以改善系統的電池、CPU 和記憶體使用量。
若要提供您已註冊接收的通知,BITS 會先嘗試呼叫您可能附加之任何現有回呼對象的對應方法。 如果沒有現有的物件,或該現有物件已中斷連線(通常是因為應用程式終止的結果),BITS 會使用通知 CLSID 呼叫 CoCreateInstance 來具現化新的回呼物件,並將使用該對象進行任何進一步的回呼,直到它中斷連線,或是由 新的 IBackgroundCopyJob 呼叫取代:SetNotifyInterface。
不同於回呼物件,如果 BITS 服務或系統關閉並重新啟動,則回呼 CLSID 會與其對應的 BITS 作業一起保存。 您的應用程式可以在結束之前或任何其他時間,通過將通知 CLSID 設為 GUID_NULL 來清除任何先前設定的通知 CLSID。但是,如果您的應用程式已註冊讓 COM 啟動它,以回應特定於您的 CLSID 的 CoCreateInstance 請求,則您的應用程式可能會偏好保留已註冊的通知 CLSID。 請注意,如果多個應用程式設定呼叫 BITS_JOB_PROPERTY_NOTIFICATION_CLSID 屬性,要設定的最後一個 CLSID 就是 BITS 將用來具現化回呼物件的 CLSID ,其他 CLSID 將不會具現化。 同樣地,如果一個應用程式註冊 CLSID,而另一個應用程式會註冊回呼物件,則優先套用回呼物件的一般規則,而且除非清除回呼物件或中斷聯機,否則不會使用 CLSID。
下列範例示範如何註冊 CLSID 通知。 此範例假設 IBackgroundCopyJob5 介面指標有效,而且您的應用程式已經註冊為實作 CNotifyInterface 類別的跨進程 COM Server。 如需下列範例中使用的 CNotifyInterface 範例類別的詳細資訊,請參閱 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.
}