[英]My BackgroundWorker still blocks my UI
我在一個類中有一個耗時的方法,該類沒有源。 調用此方法時,我不想阻止UI。 我一直在嘗試使用BackgroundWorker來做到這一點。 我從btn_Click事件處理程序調用RunWorkerAsync。 當我在工作線程之外創建dllClass實例時(如下所示),UI凍結,直到操作完成。 該操作還阻止計時器計時。
public static dllClass dllClassInstance = new dllClass();
void worker1_DoWork(object sender, DoWorkEventArgs e)
{
dllClassInstance.TimeConsumingMethod();
}
另一方面,如果我在工作線程(例如下一個代碼段)中實例化該類,則它將按預期工作。
void worker1_DoWork(object sender, DoWorkEventArgs e)
{
dllClass dllClassInstance = new dllClass();
dllClassInstance.TimeConsumingMethod();
}
使用后者的問題在於,我需要訪問該特定工作程序之外的類實例,因為我必須在耗時的方法之前和之后調用其他方法。 我還嘗試通過e.Argument將類實例傳遞給BackgroundWorker,但這也導致UI凍結。 有沒有人有建議如何在不阻止UI的情況下調用該方法?
有沒有人有建議如何在不阻止UI的情況下調用該方法?
不知道dllClass
發生了什么,就無法確定。
通常,這兩個代碼都不會導致UI凍結。 我懷疑dllClass
在其構造函數中捕獲了當前的SynchronizationContext
,並在TimeConsumingMethod
內部使用了它,從而導致阻塞。 如果是這種情況,您可能會在DoWork處理程序中構造該類,但是將其范圍限定為該類,這可能會起作用。 但是,如果它正在捕獲同步上下文,則該類很可能具有線程親和力,並期望在UI線程上運行。
您可以嘗試在處理程序中構造實例,如下所示:
public dllClass dllClassInstance;
void worker1_DoWork(object sender, DoWorkEventArgs e)
{
dllClassInstance = new dllClass(); // Construct here
dllClassInstance.TimeConsumingMethod();
}
正如我所說,這可能會起作用,但它可能還有其他副作用。 我將驗證dllClass
沒有要求它在UI線程上運行的線程相似性規則。
這可能是因為您的dllClass
。 除非有人要確保實例上的所有調用都在同一線程中處理,否則您所看到的不會發生。 如果dllClass
在其構造函數中使用了調度程序,然后TimeConsumingMethod
通過該調度程序調用實際的處理,您將看到凍結的UI。
正如Reed指出的那樣,如果不知道該類的內部是什么,可能很難真正解決。 但是,如果您還有其他需要加載/准備,設置的內容,則將讓您的后台工作程序類“ ReportsProgress” = true,並在其啟動時立即調用一個方法,該方法將基於ex獲取和/或准備其他設置:進度為1(開始),然后執行長流程的其他元素,然后報告進度,結果值為99(結束),然后從中進行清理。
聽起來有幫助嗎? 您仍然可以將所有內容封裝到單個后台工作程序類中。
我正在VB.net應用程序上工作,並且遇到了與用於與安捷倫設備通信的Visa Com 3.0驅動程序的同一問題。 這是我解決的方法:
Dim task = New Threading.Tasks.Task(Of dllClass)(Function()
Return New dllClass()
End Function)
task.Start()
task.Wait()
public static dllClass dllClassInstance = task.Result;
void worker1_DoWork(object sender, DoWorkEventArgs e)
{
dllClassInstance.TimeConsumingMethod();
}
本質上,我在新線程中創建了dllClass實例,但立即放棄了該線程並保留了引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.