簡體   English   中英

從不同類中的不同線程更新UI

[英]Update UI from a different thread in a different class

我有包含要更改的列表框的主窗體類。 該框將填充以費時的方法創建的項目。 現在看起來像這樣(手動創建示例,可能不是有效的C#):

List<string> strings = StaticClassHelper.GetStrings(inputString);
foreach(string s in strings)
{
    listBox1.Add(s);
}

//meanwhile, in a different class, in a different file...

public static List<string> GetStrings(inputString)
{
    List<string> result = new List<string>();
    foreach(string s in inputString.Split('c'))
    {
        result.Add(s.Reverse());
        Thread.Sleep(1000);
    }
    return result;
}

我想做的是在找到新字符串時定期更新列表框。 當線程方法位於同一類中時,我發現其他答案可行,因此您可以設置事件處理程序。 我在這里做什么?

這是我喜歡的方式,我在這樣的表單上創建一個方法:

public void AddItemToList(string Item)
{
   if(InvokeRequired)
      Invoke(new Action<string>(AddItemToList), Item);
   else
      listBox1.Add(Item);
}

在這種情況下,我更喜歡調用以確保同步添加項目,否則它們可能會混亂。 如果您不關心訂單,則可以使用BeginInvoke ,它將更快一點。 由於此方法是公共的,因此只要您可以獲取對表單的引用,就可以從應用程序中的任何類進行所有操作。

這樣做的另一個優點是,可以從UI線程或非UI線程調用它,並且它會確定是否需要Invoke 這樣,您的調用方就不必知道他們在哪個線程上運行。

更新為了解決您對如何獲得對Form的引用的評論,通常在Windows Forms應用程序中,您的Program.cs文件如下所示:

static class Program
{
   static void Main() 
   {
       MyForm form = new MyForm();
       Application.Run(form);  
   }

}

這通常是我要做的,特別是在“單一表單”應用程序的情況下:

static class Program
{
   public static MyForm MainWindow;

   static void Main() 
   {
       mainWindow = new MyForm();
       Application.Run(form);  
   }

}

然后,您可以使用以下任何地方在幾乎任何地方訪問它:

Program.MainWindow.AddToList(...);

包含ListBox的類需要公開一種添加字符串的方法-由於此方法可能在其他線程上調用,因此需要使用

listBox1.Invoke( ...)

創建線程安全的調用機制

您是否可以將GetStrings重寫為迭代器? 然后,在您的UI中,您可以啟動一個后台線程,該線程在GetStrings的結果上進行迭代,每次都更新列表框。 就像是:

public static System.Collections.IEnumerable GetStrings(inputString)
{
    foreach(string s in inputString.Split('c'))
    {
        yield return s.Reverse();
        Thread.Sleep(1000);
    }
}

在用戶界面中(假設使用C#4):

Task.Factory.StartNew(() =>
{
    foreach (string s in StaticClassHelper.GetStrings(inputString))
    {
        string toAdd = s;
        listBox1.Invoke(new Action(() => listBox1.Add(toAdd)));
    }
}

可能更清潔的解決方法,但這應該可以為您提供所需的東西。

暫無
暫無

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

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