簡體   English   中英

我的BackgroundWorker仍然阻止我的UI

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM