簡體   English   中英

GUI凍結-無效的操作異常c#

[英]GUI Freezes - Invalid Operation Exception c#

我在c#中有一個GUI,您可以在其中打開日志文件。 該程序具有2個主要功能:setTextMessageTextBox(),可在需要時更新GUI(在每次操作后提供適當的消息)

private static void setTextMessageTextBox(){
  MyProject.mainForm update = new MyProject.mainForm();

  //messageTextBox.Text is set by default to "Open the file".

  const string msg_0 = "Open the file";
  const string msg_1 = "Press button to start reading";
  const string msg_2 = "Please wait, Reading in progress";
  const string msg_3 = "Reading finished";

  string textCurrent = update.messageTextBox.Text;

  switch (textCurrent){
    case msg_0 :
      update.messageTextBox.Text = msg_1;
      break;
    case msg_1 :
      update.messageTextBox.Text = msg_2;
      break;
    case msg_2 :
      update.messageTextBox.Text = msg_3;
      break;
    case msg_3 :
      //msg_4 is a global variable with the result
      update.messageTextBox.Text = msg_4;
      break;
  }//switch
}//method setMessageBoxTest

然后,我有完成所有工作的analytics()方法(日志非常大,因此最多需要1分鍾才能完成)。

private void analyze(){
  //reading log
  //cutting log
  //calls other classes to take what pieces are needed
  //calls other classes to decode pieces
  //saves the final result to msg_4
}

最后,我有按鈕Anal​​yzeButton觸發:

private void analyzeButton_Click(object sender, EventsArgs e){

  setTextMessageTextBox();

  analyze();

  setTextMessageTextBox();

}//analyzeButton

結果是僅在分析功能完成后,GUI才會凍結,並且文本框將被更新。

我試過了:

MethodInvoker startAnalyze = new MethodInvoker(analyze);
startAnalyze.Invoke();

但是GUI仍然凍結

我試圖調用setTextBox

MethodInvoker setMessage = new MethodInvoker(setMessageTextBox);
setMessage.Invoke();

GUI仍然凍結

我嘗試將兩者與方法調用程序一起使用,但引發了無效操作異常。

最后,我使用begin_invoke而不是Invoke進行分析:

MethodInvoker beginning = new MethodInvoker (analyze);
beginning.BeginInvoke(null, null)

GUI不再凍結,但textBox仍未更新。

我已經閱讀了有關BackgroundWorker的信息,但也許我錯過了一些東西,但根本沒有用。 任何人都有我所缺少的線索,或者是否有更好的解決方法? 感謝您的時間。


更新:@SriramSakthivel我將新實例的創建移到了全局變量級別,但是結果仍然相同。 GUI不會凍結,但不會更新textBox。 在我按下按鈕之前,它已更新。 例如 文本從“打開文件”更改為 按下”按鈕以開始閱讀,但是在按下按鈕后,文本框保持原樣。 將新實例設置為全局實例后,我通過兩種方式進行了測試:調用setMessageTextBox,以及在執行適當的操作之前和之后手動分配新消息。 恩。 'update.messageTextBox.Text =“分析”; update.messageTextBox.Refresh(); 分析(); '我嘗試使用和不使用.Refresh(),但仍然沒有任何改變。

首先,在每次調用setTextMessageTextBox()時都沒有必要為表單創建新實例。 我很確定您不想為每條日志消息彈出一堆窗口(實際上,您甚至沒有顯示這些新表格)。

接下來,必須僅從UI線程更新GUI元素。 如果您要在UI線程上進行長時間運行的操作,並設置不同控件的progress屬性,則在完成作業之前不會重繪它們,因為設置這些屬性(如Text )只會使它們無效,並且基本上告訴運行時重繪下次UI線程別無它們時。

換句話說,無論是BackgroundWorkerTask還是普通Thread ,都必須使用后台工作程序來執行此操作。 然后,此后台線程應調用progress update方法,該方法將確保將update操作調度到UI線程(現在也可以自由地對其進行重新繪制):

class MyForm : Form
{
    public void ShowMessage(string msg)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new Action<string>(ShowMessage, msg));
            return;
        }

        this.messageTextBox.Text = msg;
    }
}

然后僅從此Form實例調用它。

暫無
暫無

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

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