在我的小測試程序中,我想檢查機器的某些部分,同時更新標籤和進度條(基本上是一個啓動窗體,通知用戶關於機器啓動的進度)。 爲此,我已經閱讀了關於在後臺工作中添加東西以及通過ReportProgress更新UI的信息。這工作正常。通過在WinForm中顯示UI中的消息框(來自backgroundworker)來阻止Workerthread
所有部件檢查都是在do-while-loop內完成的,只有在零件檢測成功時纔會執行。如果一個零件檢測成功,則循環結束,並且工作線程移動到下一個零件的下一個循環,直到檢查完所有零件。
現在,如果一個部分有缺陷,並且測試不成功,我想顯示一個MessageBox,通知用戶有關缺陷。在這樣做的時候,WorkerThread應該停止,等待用戶按「重試」或「確定」。到目前爲止,無論是新聞發佈會從一開始就開始當前的do-while-loop,直到問題得到解決。 如果我只在我的循環中放入MessageBox.Show(「test」),它會在完成backgroundthread結束後顯示,並在顯示消息框後再次啓動後臺線程。
這裏我的代碼:
namespace USBSerialTest
{
public partial class test1 : Form
{
private int check;
private int Progress;
private byte[] Check_byte_Board1 = { 0x02, 0x01, 0x64, 0x06, 0x00, 0x00, 0x00, 0x80, 0xed };
private byte[] Check_byte_Board2 = { 0x02, 0x01, 0x64, 0x06, 0x00, 0x00, 0x00, 0x81, 0xee };
public test1()
{
InitializeComponent();
Shown += new EventHandler(test1_LoadForm);
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
//backgroundWorker1.ProgressChanged += ShowWarning; Not working
}
void test1_LoadForm(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Progress = 0;
backgroundWorker1.ReportProgress(Progress, "Checking for Board Function");
do //check if Board retruns an error
{
Motor.Instance.Check_Board();
if (Motor.Instance.buf.SequenceEqual(Check_byte_Board1) || Motor.Instance.buf.SequenceEqual(Check_byte_Board2))
{
check = 1;
Progress += 10;
//MessageBox.Show("test"); not working, just for testing here
backgroundWorker1.ReportProgress(Progress, "Checking for Board Function");
}
else
{
//here is the important part, when there is an error, I want to display the warning message
//and start the do-while loop from the start, all other message boxes where just to
//test around if the general principle works
DialogResult result = MessageBox.Show("Boarddriver produce Errorcode ... Please Consult");
if (result == DialogResult.Retry)
{
check = 0;
}
else
{
check = 0;
}
}
} while (check != 1);
backgroundWorker1.ReportProgress(Progress, "Succes");
}
// Back on the 'UI' thread so we can update the progress bar
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = e.UserState.ToString();
//MessageBox.Show(e.UserState.ToString()); not working
}
private static void ShowWarning(object sender, ProgressChangedEventArgs e)
{
MessageBox.Show("test box"); //not working, displays a Messagebox each time
//ProgressChanged is triggered, but does not block the worker thread.
}
}
}
所以,我怎麼能停止與一個消息框,警告工作者線程,並繼續它(或恢復電流回路)?
我知道這個問題以前曾以類似的方式提出過,那就是我得到了我的「試用解決方案」,這是我玩過的。我還讀到它並沒有真正批准用MessageBoxes來發送用戶郵件,但我需要某種用戶輸入(其他粗略的想法是將標籤更改爲警告,並在錯誤事件觸發時顯示/隱藏按鈕 – Chris
你的問題很混亂,也不清楚,用你發佈的代碼,在DoWork事件處理程序中調用'MessageBox.Show()'的地方,實際上應該立即顯示消息框,代碼應該等待在循環中的Show()調用中,直到用戶已經解除了消息框,這似乎符合你的標準,除此之外,還不清楚你的循環實際在做什麼;它似乎並沒有執行多個測試,正如你的敘述所描述的那樣,並且似乎沒有任何機制可以根據用戶輸入或其他方式重新啓動失敗測試。 –
個人而言,我不會使用'BackgroundWorker'。它的時間很不錯,但它已經被取代b y'Task.Run()'和相關的框架和語言特性。我猜想解決方案的最好方法是使你的'LoadForm'事件處理程序'async',使用'Task.Run()'來調用每個測試,並將所有的UI處理直接放在'LoadForm事件處理程序方法。但有了這樣一個令人困惑的問題,我不想嘗試發表一個完整的答案。如果你想要的話,請改善你的問題。 –