【发布时间】:2014-02-23 09:56:01
【问题描述】:
下面的代码在后台工作线程中运行:
while (StaticVideoList.DecodedFramesList.Count > 0)
{
if (StaticVideoList.DecodedFramesList.ContainsKey(a))
{
byte[] output;
if(StaticVideoList.DecodedFramesList.TryRemove(a, out output))
{
MemoryStream ms = new MemoryStream(output);
Image img = Image.FromStream(ms);
a++;
this.Invoke((Action)delegate
{
textEdit7.Text = "Num Frame: " + a.ToString() + " / " + (1000m / ((decimal)sw.ElapsedMilliseconds / (decimal)a)).ToString();
pictureEdit1.Image = img;
});
// Works if I do this.. 10 is the minium.
//System.Threading.Thread.Sleep(10);
}
}
}
我的问题是,除非我在循环中添加 Thread.Sleep(10),否则不会进行所有 Invoke 调用。调用了整个循环,但只进行了 20% 的调用调用(它在然后停止时获得了 20%,而不是间歇性结果)
如果我逐步调试它也可以正常工作。
我认为问题可能是当后台工作线程完成时,它会取消任何由它发出的调用。但是放置一个 Thread.Sleep(10000) 来让后台线程挂起更长的时间并没有做任何事情。
调用调用的速度是否有限制?
BeginInvoke 也有同样的“问题”
【问题讨论】:
-
backgroundworker 包含更新进度的功能
-
我已经用它作为 reportProgress 的替代方法并在 userState 参数中传递数据但我仍然对上述为什么不起作用感到困惑
-
当您说 “不起作用” 时,您的意思是实际上错过了 Invoke 调用还是 UI 缺少更新?您确定更新不会发生得太快以至于您没有注意到吗?
-
@James 它停止了 20%。我可以看到它在前 110/500 张图像中运行良好。然后它就停在那个位置。即没有贯穿到其余部分。所以绝对不能跑得太快,否则会以 500/500 结束
-
您正在烧毁 UI 线程。在关键点,它只是处理 Invoke() 调用,不再做任何其他事情。就像绘制图片框和响应输入一样。 not 调用 Sleep() 是没有意义的,您需要以恒定的速率调整图像的显示速度。附带的好处是,您也不必再对 UI 线程进行喷管并使其变得紧张。另一个重要的问题是您不处理旧图像。
标签: c# multithreading