你好Stackoverflowers!
我这里有一个奇怪的情况。我写了一个小的C#工具来测量通过usb发送请求所花费的时间,并等到响应到来。沟通没有问题,设备也没有问题。
我在GUI上放了一个简单的TextBox和一个“开始”按钮。 按“开始”启动一个带有循环的线程(在TextBox中定义的循环)发送请求并接收答案。在GUI线程中,您可以看到显示状态的进度条。
当我按下“开始”时,每个命令和响应(平均)测量大约15毫秒,这是相当长的时间。
当我按下“开始”并在TextBox内部单击(仅将光标设置在内部)时,工作线程以每个命令和响应的平均时间1.6毫秒运行。
这在我的案例中是可重现的。我甚至放入一个新的,完全没用的TextBox。当点击内部时,线程加速,当我聚焦另一个元素时,如滑块,线程再次减速。
有没有人听说过类似的东西,可以向我解释,为什么会这样?甚至更好,我怎么能避免这种行为?
供参考:
- 我尝试了BackgroundWorker和Thread,行为相同。
- 为了抽出时间,我正在使用.NET的秒表
- 在GUI线程中执行测量方法不会改变任何内容。编辑:再次尝试,一切都应该是。但现在我遇到了问题,GUI冻结了,因为我正在使用它的线程
- 删除进度条不会改变任何内容。
非常感谢!
编辑:
private void tbAmount_Copy_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if (String.IsNullOrEmpty(tbDevAddrTime.Text))
return;
pbTimeMeasure.Value = 0;
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(StartTimeMeasureHandler);
worker.RunWorkerAsync();
}
}
private void StartTimeMeasure()
{
int address = 1;
int loops = 1;
DispatchIfNecessary(() =>
{
address = Convert.ToInt32(tbDevAddrTime.Text);
loops = Convert.ToInt32(tbAmount_Copy.Text);
pbTimeMeasure.Maximum = loops;
});
System.Diagnostics.Stopwatch stopwatchLong = new System.Diagnostics.Stopwatch();
System.Diagnostics.Stopwatch stopwatchShort = new System.Diagnostics.Stopwatch();
var cmd = String.Format(":{0:X3}4010200300000000\r", RequestAddress + address);
for (int i = 0; i < loops; i++)
{
stopwatchLong.Start();
//SND
_canbus.Write(cmd, cmd.Length, ref _bytesWritten);
stopwatchShort.Start();
Thread.Sleep(1);
//RCV
var answer = ReadContent();
stopwatchShort.Stop();
stopwatchLong.Stop();
DispatchIfNecessary(() =>
{
pbTimeMeasure.Value++;
});
}
Double resLong = Convert.ToDouble(stopwatchLong.ElapsedMilliseconds);
Double resLongAvg = resLong / loops;
Double resShort = Convert.ToDouble(stopwatchShort.ElapsedMilliseconds);
Double resShortAvg = resShort / loops;
DispatchIfNecessary(() =>
{
lbTotalResLong.Content = resLong.ToString();
lbTotalResShort.Content = resShort.ToString();
int length = 5;
if (resLongAvg.ToString().Length < 5)
{
length = resLong.ToString().Length;
}
if (resShortAvg.ToString().Length < length)
{
length = resShortAvg.ToString().Length;
}
lbAvgResLong.Content = resLongAvg.ToString().Substring(0,length);
lbAvgResShort.Content = resShortAvg.ToString().Substring(0,length);
});
}