簡體   English   中英

c# backgroundworker 與一個正在運行的類

[英]c# backgroundworker with a running class

我想從表單啟動后台工作人員。

    private void button2_Click(object sender, EventArgs e)
    {
        backgroundWorker2.RunWorkerAsync();
    }

    private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
    {
        ExtClass.doit("Hello", "World");
    }

后台工作人員在文本框中插入“Hello World”。

    public static void doit(string a, string b)
    {
        Form F1 = Application.openForms[0] as Form1;
        F1.textbox1.Text = a + b;
    }

但我得到一個例外。 如何從后台工作人員訪問表單控件?

后台工作人員在后台工作(顧名思義)。

所有Control對象都設計為不是線程安全的。 您只能從創建它們的線程(通常稱為 UI 線程)訪問它們。

雖然有多種方法可以在 UI 線程中執行代碼塊,但您應該首先從根本上了解您的設計。 使用后台工作者的想法是在后台做工作; 涉及與用戶界面交互的工作。

如果您需要從 UI 獲取信息來完成工作,您應該在啟動后台工作程序之前獲取它並將信息作為參數傳遞給工作方法。 如果要使用操作結果更新 UI,則應使用已完成的事件處理程序。 (它將始終在 UI 線程中運行;BGW 類會為您處理這些。)如果您需要使用進度更新進度條或標簽,您應該使用進度更新事件並在 BGW 上調用更新進度。 進度更新事件也在 UI 線程中運行。

F1.Invoke(new MethodInvoker(()=> { F1.textbox1.Text = a + b; }));

您需要有一個對 Form 的引用,並使用傳入修改 Form 的方法的 Invoke 或 Begin/End Invoke。

要保存引用,我建議您使用 The RunWorkerAsync(Object)傳遞控件並通過 DoWork Arg 的Argument獲取引用。

為了解決這個問題,你應該建立Form1參考,而不是參考Form ,因為Form沒有textBox1領域,但你的Form1做,這是異常的來源,你應該改變這樣的:

Form F1 = Application.OpenForms[0] as Form1;

進入這個

Form1 F1 = Application.OpenForms[0] as Form1;

然后您應該調用對 textBox1 字段的訪問(如果需要),因為您是從另一個線程訪問它(DoWork 在另一個線程中執行,但 RunWorkerCompleted 在 UI 線程中)。 因此,完整的代碼應該是這樣的:

public static void doit(string a, string b)
{
    Form1 F1 = Application.openForms[0] as Form1;
    if(F1.InvokeRequired)
        F1.Invoke(new MethodInvoker(delegate() { F1.Text = a + b; });
    else
        F1.Text = a + b;
}

我需要一點幫助。

我在另一個 c# 項目中運行后台工作程序。 問題是這個項目有一個巨大的組合框和文本框,后台工作人員在運行時訪問。

那么我如何在 GUI 中訪問控件而不將它們全部放在一個,

textbox1.Invoke(new MethodInvoke(()............})); 選項...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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