2015-02-09 38 views
0

我有一個簡單的while循環,它允許我在文本框中查找文本,但是當我搜索文本框中出現多次的單詞時,它鎖定了一段時間的界面。我想將它移動到後臺工作,但我不認爲這是可以做到的,因爲界面元素(即textbox3.text)在主線程中。當涉及主界面元素時,我如何能夠創建一個後臺工作者?搜索和高亮功能的後臺工作

我在網上找到了不錯的信息,但是我在實施其他解決方案時遇到了困難,我已經閱讀了我的特定情況。

public void button2_Click(object sender, EventArgs e) 
    { 
     //Highlight text when search button is clicked 
     int index = 0; 
     while (index < dragDropRichTextBox1.Text.LastIndexOf(textBox3.Text)) 
     { 
      dragDropRichTextBox1.Find(textBox3.Text, index, dragDropRichTextBox1.TextLength, RichTextBoxFinds.None); 
      dragDropRichTextBox1.SelectionBackColor = Color.Orange; 
      index = dragDropRichTextBox1.Text.IndexOf(textBox3.Text, index) + 1; 
     } 
    } 

感謝您的幫助。

回答

-1

你只需要使用調用,當你操縱UI元素在你的後臺線程

https://msdn.microsoft.com/en-us/library/vstudio/ms171728(v=vs.100).aspx

+1

這裏所有的實際工作都是由richtextbox本身完成的,因此99%的CPU將用於UI線程。沒有必要只是圍繞一個調用包裝一個線程。 – Blorgbeard 2015-02-09 20:43:27

+0

我認爲他的問題的重點是如何將該工作移動到後臺線程中,以便在搜索功能運行時UI不會掛起。使用後臺線程來調用UI線程來完成所有工作並不會改善用戶體驗,這似乎是這裏的目標。 – Levesque 2015-02-10 19:46:56

-1

可以調用Invoke方法上的控制。

dragDropRichTextBox1.Invoke((MethodInvoker) delegate { 
    //Your code goes here for whatever you want to do. 
} 

);

這應該解決您的問題。

+1

當他已經通過Button Click處理程序在主UI線程中運行時,這根本無濟於事...... – 2015-02-09 16:40:25

1

我猜你想要做的是創建子線程做的工作不阻塞UI線程(僞代碼,又名未測試):

public void button2_Click(object sender, EventArgs e) 
{ 
    // Copy text in a non-thread protected string, to be used within the thread sub-routine. 
    string searchText = textBox3.Text; 
    string contentText = dragDropRichTextBox1.Text; 

    // Create thread routine 
    ThreadPool.QueueUserWorkItem(o => { 

     // Iterate through all instances of the string. 
     int index = 0; 
     while (index < contentText.LastIndexOf(searchText)) 
     { 
      dragDropRichTextBox1.Invoke((MethodInvoker) delegate { 

       // Update control within UI thread 
       //Highlight text when search button is clicked 
       dragDropRichTextBox1.Find(searchText, index, contentText.Length, RichTextBoxFinds.None); 
       dragDropRichTextBox1.SelectionBackColor = Color.Orange; 
      } 

      // Go to next instance 
      index = contentText.IndexOf(searchText, index) + 1; 
     }    
    }); 
} 

再次,這是未經測試,但會給你的想法。

- 編輯 -

你不需要線程可言,做一個dragDropRichTextBox1.SuspendLayout()dragDropRichTextBox1.ResumeLayout()之間所有的工作就足夠了。

private void button1_Click(object sender, EventArgs e) 
    { 
     // Copy text in a non-thread protected string, to be used within the thread sub-routine. 
     string searchText = textBox1.Text; 
     string contentText = richTextBox1.Text; 

     // Suspend all UI refresh, so time won't be lost after each Find 
     richTextBox1.SuspendLayout(); 

     // Iterate through all instances of the string. 
     int index = 0; 
     while (index < contentText.LastIndexOf(searchText)) 
     { 
      //Highlight text when search button is clicked 
      richTextBox1.Find(searchText, index, contentText.Length, RichTextBoxFinds.None); 
      richTextBox1.SelectionBackColor = Color.Orange; 

      // Go to next instance 
      index = contentText.IndexOf(searchText, index) + 1; 
     } 

     // Finally, resume UI layout and at once get all selections. 
     richTextBox1.ResumeLayout(); 
    } 
+0

我認爲這可以工作,除了dragDropRichTextBox1是RichTextBox類型,它也是主線程的一部分。我需要創建一個DragDropRichTextBox的新實例:RichTextBox來替換dragDropRichTextBox1嗎?如果我這樣做,我不知道我將如何更新用戶界面。希望這是有道理的。 – Gernatch 2015-02-09 17:01:55

+0

是的,也許用richtextbox.begininvoke()替換richtextbox.invoke(),那會消除你的阻塞? (對不起,我不能測試它atm) – DarkUrse 2015-02-09 17:26:49

+0

沒有必要道歉,任何感激。更正雖然,以前的建議編譯得很好。我最初錯過了一行代碼。不幸的是,它沒有給出預期的結果。與其等待很長時間讓所有文本同時突出顯示,不如逐一突出顯示搜索字符串。在此期間,界面仍然被鎖定。 – Gernatch 2015-02-09 17:59:14