2016-02-19 66 views
1

不適當的標題。我有如下程序當方法運行時,Richbox不更新

int status = 100; 
richTextBox1.AppendText("Starting Process....." + "\n"); 

status = comm.WriteData(cmd1); 
if (status == 0) 
{ 
    richTextBox1.AppendText("COMMAND 1 OK" + "\n"); 
} 
else 
{ 
    richTextBox1.AppendText("COMMAND 1 NOT OK" + "\n"); 
} 
richTextBox1.AppendText("Gathering signal from product sensor....." + "\n"); 
status = comm.WriteData(cmd2); 
if (status == 0) 
{ 
    richTextBox1.AppendText("COMMAND 2 OK" + "\n"); 
} 
else 
{ 
    richTextBox1.AppendText("COMMAND 2 NOT OK" + "\n"); 
} 
richTextBox1.AppendText("Measuring current value" + "\n"); 
status = comm.WriteData(cmd3); 
if (status == 0) 
{ 
    richTextBox1.AppendText("COMMAND 3 OK" + "\n"); 
} 
else 
{ 
    richTextBox1.AppendText("COMMAND 3 NOT OK" + "\n"); 
} 

這將在按鈕單擊事件上執行。像這樣我需要發送130個命令。整個過程大約需要6分鐘。代碼工作正常。但在執行所有命令(6分鐘)之前,RichTextBox看起來是空的。每個命令執行後,我需要向操作員顯示消息,無論命令是OK還是NOT OK。我甚至試圖在每個命令之間給予延遲。但無法達到我所需要的。請支持解決此問題。

+0

你在寫數據(CMD)的代碼是什麼?你可以使它異步並等待它在你稱之爲的地方。 – CarbineCoder

+0

其通過串口通訊將ASCII值賦予儀器 – Vasanth

+0

我已經自由地編輯了你的標題,以便真正匹配問題 – Jcl

回答

3

我在這裏使用BackgroundWorker,並使用ReportProgress添加到文本框。喜歡的東西(我就放心了):

public void ButtonClick() 
{ 
    // Since your code will now be async, you should need to handle reentrance here 
    var worker = new BackgroundWorker(); 
    worker.ReportsProgress = true; 
    worker.ProgressChanged += ProgressLog; 
    worker.DoWork += TestComm; 
    worker.RunWorkerAsync(); 
} 

private void ProgressLog(object sender, ProgressChangedEventArgs e) 
{ 
    richTextBox1.AppendText(e.UserState.ToString() + Environment.NewLine); 
} 

private void TestComm(object sender, DoWorkEventArgs e) 
{   
    var worker = sender as BackgroundWorker; 
    worker.ReportProgress(0, "Starting Process....."); 
    // Sub-optimal way to construct a string :-) 
    worker.ReportProgress(0, "COMMAND 1 " + (comm.WriteData(cmd1) == 0 ? "OK" : "NOT OK")); 
    worker.ReportProgress(0, "Gathering signal from product sensor....."); 
    worker.ReportProgress(0, "COMMAND 2 " + (comm.WriteData(cmd2) == 0 ? "OK" : "NOT OK")); 
    worker.ReportProgress(0, "Measuring current value"); 
    worker.ReportProgress(0, "COMMAND 3 " + (comm.WriteData(cmd3) == 0 ? "OK" : "NOT OK")); 
    // etc. 
} 

作爲一個側面說明,如果你做的是「顯示標題字符串」,「運行命令」,寫「命令#OK /不OK」,這可能是很容易重構成一個循環,但我會留給你:-)

此外,由於你的代碼現在是異步的,你需要處理再次進入按鈕的事件Click,因爲用戶現在可以點擊運行測試時的按鈕(因此可能會同時運行兩個測試,如果您使用的是通信端口,則可能無法執行此測試)。

這可能非常簡單,只需在創建工作人員時禁用按鈕,然後在BackgroundWorker.RunWorkerCompleted事件中再次啓用該按鈕,或者可以根據需要將其複雜化(取消初始測試並再次啓動,或者不需要)。

正如評論所述,您還需要再次入場幫助。最簡單的方法是這樣的:

public void ButtonClick() 
{ 
    // Disable the button  
    myButton.Enabled = false; 

    var worker = new BackgroundWorker(); 
    worker.ReportsProgress = true; 
    worker.ProgressChanged += ProgressLog; 
    worker.DoWork += TestComm; 

    // Re-enable the button when the worker has completed (or failed) 
    worker.RunWorkerCompleted += (o,e) => myButton.Enabled = true; 
    worker.RunWorkerAsync(); 
} 
3

您需要在單獨的線程中編寫數據。發生什麼事是你的UI線程正在等待你的函數執行完成,然後才能恢復正常的操作,比如更新控件。你可以在winforms的BackgroundWorker Class的文檔中閱讀更多內容。

1

嘗試每個AppendText通過這個代碼後:

richTextBox1.Refresh(); 
+1

雖然這會起作用,但Application.DoEvents()也會起作用,但是如果還有其他更好的解決方案,我從來不會從道德上推薦此(或「DoEvents」):-) – Jcl