在我的小测试程序中,我想检查机器的某些部分,同时更新标签和进度条(基本上是一个启动窗体,通知用户关于机器启动的进度)。 为此,我已经阅读了关于在后台工作中添加东西以及通过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事件处理程序方法。但有了这样一个令人困惑的问题,我不想尝试发表一个完整的答案。如果你想要的话,请改善你的问题。 –