大家。基本上我想要实现的工作流程如下:
由于截止日期不是到目前为止,我从一个名为Termie的开源项目开始,该项目实现了一个简单的串行接口,也提供了直接开箱即用的通信配置表单。 要执行多线程操作,我使用BackgroundWorker
private BackgroundWorker backgroundPressure = new BackgroundWorker();
我在我的主要表单的构造函数方法中初始化:
public consoleForm()
{
...
// Initialize background worker to separate GUI from data collection
backgroundPressure.DoWork += new DoWorkEventHandler(backgroundPressure_DoWork);
backgroundPressure.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundPressure_RunWorkerCompleted);
backgroundPressure.ProgressChanged += new ProgressChangedEventHandler(backgroundPressure_ProgressChanged);
backgroundPressure.WorkerReportsProgress = true;
backgroundPressure.WorkerSupportsCancellation = true;
}
传输开始时,将调用backgroundPressure的RunworkerAsync方法:
if(!backgroundPressure.IsBusy)
{
backgroundPressure.RunWorkerAsync();
}
正确处理DoWork事件,我的程序正确输入了具有以下代码的处理程序方法:
protected void backgroundPressure_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker sendingWorker = (BackgroundWorker)sender;
BeginInvoke((MethodInvoker)delegate
{
pressureChart.Series.Clear();
pressureData.Clear();
timeAxis.Clear();
foreach (string name in pressureSensorNames)
{
pressureChart.Series.Add(name);
}
});
Stopwatch sto = new Stopwatch();
int linenumber = syncWithLogger("pres");
int debugs = linenumber;
while (linenumber == -1)
{
Thread.Sleep(100);
BeginInvoke((MethodInvoker)delegate
{
linenumber = syncWithLogger("pres");
});
}
sto.Start();
long elapsed = sto.ElapsedMilliseconds;
while (!sendingWorker.CancellationPending)
{
BeginInvoke((MethodInvoker)delegate
{
try
{
elapsed = sto.ElapsedMilliseconds;
pressureChartUpdate(linenumber, elapsed);
imuChartUpdate(linenumber + 1, elapsed);
linenumber += 2;
Thread.Sleep(100);
}
catch(Exception ex)
{
if(ex is FormatException)
{
Thread.Sleep(100);
// Wait and go on
}
else if(ex is ArgumentOutOfRangeException)
{
Thread.Sleep(100);
// Wait and go on
}
}
});
sendingWorker.ReportProgress(10, 100);
BeginInvoke((MethodInvoker)delegate
{
samplesAcquiredStatus.Text = sto.ElapsedMilliseconds.ToString();
});
e.Cancel = true;
sto.Stop();
}
}
在while (!sendingWorker.CancellationPending)
区块之前,一切都运作良好。当它进入时,GUI冻结,Visual Studio报告内存占用的渐进和快速增加,我真的不理解,而没有抛出异常。
如果我注释掉调用GUI更新方法的代码
,也会发生这种行为pressureChartUpdate(linenumber, elapsed);
imuChartUpdate(linenumber + 1, elapsed);
我已经单独测试过解析器,所以我认为问题在于多线程操作。任何人都可以帮助我吗?
答案 0 :(得分:1)
一个问题是在UI线程上调用Thread.Sleep
。这将根据定义阻止您的UI并使其无响应。一旦它处于睡眠状态,它就无法执行任何操作。