【问题标题】:Multiple Invoke / BeginInvoke calls not finishing without Thread.Sleep()没有 Thread.Sleep() 的多个 Invoke / BeginInvoke 调用无法完成
【发布时间】: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


【解决方案1】:

Invoke 对我来说似乎是一条红鲱鱼。循环似乎“停止”但在您睡眠线程时有效,这一事实向我表明您有竞争条件。

我的建议是将您的循环剥离到最低限度并重建它,直到您再次遇到问题 - 这应该有助于您确定问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2011-04-16
    • 1970-01-01
    相关资源
    最近更新 更多