绘制图像的形式从一个单独的线程 [英] Draw image on a form from a separate thread

查看:120
本文介绍了绘制图像的形式从一个单独的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前工作的一个Windows.Forms的应用。它基本上是一个简单的运动检测问题

I am currently working on a Windows.Forms application. It's basically a simple motion detection problem.

我有一个表格上的一个按钮,按下时启动一个后台工作,做了以下内容:

I have a button on a form, that when pressed launches a background worker that does the following :


  1. 获取从磁盘映像

  2. 创建一个新的位图,将作为缓冲。

  3. 执行运动检测

  4. 从运动检测的结果,更新缓冲区(使用缓冲的绘图表面)

  5. 消防进度变更事件有一个参数,包括缓冲区的克隆,基本上(发件人为BackgroundWorker的).ReportProgress((位图)buffer.Clone())

  1. Fetch an image from disk
  2. Create a new bitmap, to be used as the buffer.
  3. Perform Motion Detection
  4. From the results of Motion Detection, update the buffer (using the buffer's drawing surface)
  5. Fire the Progress Changed Event with an argument consisting of a clone of the buffer, basically (sender as BackgroundWorker).ReportProgress((Bitmap)buffer.Clone())

在进度更改事件,我再画缓冲屏幕。

In the Progress Changed Event, I then draw the buffer to screen.

if (!PnlImage.IsDisposed)
            PnlImage.CreateGraphics().DrawImageUnscaled(buffer, 0, 0);



我不禁想,如果这是在屏幕上绘制更新的映像的最佳方式。任何人都可以提出任何改进,我可以做什么呢?
谢谢

I can't help wondering if this is the best way to draw the updated image on the screen. Can anyone suggest any improvements I can make? Thanks.

编辑:
因为我已经更新了程序使用.NET Framework 4中,我们不再使用一个BackgroundWorker 。相反,我们现在使用的System.Threading.Tasks命名空间,并使用调用更新从任务中的背景图片。

EDIT : I have since updated the program to use the .NET Framework 4, and we're no longer using a BackgroundWorker. Instead, we are now using the System.Threading.Tasks namespaces, and using Invoke to update the background image from within the task.

感谢所有的答复。

推荐答案

我相信您可能遇到的任何问题的根源是,任何GUI更新必须在UI线程来完成。你不能安全地更新从另一个线程的用户界面。所以,基本上,你需要做类似如下(我只是改变背景颜色作为一个例子,但你可以做任何你喜欢的):

I believe the root of any problems you may be experiencing is the fact that any GUI updates must be done on the UI thread. You cannot safely update the UI from another thread. So, basically, you need to do something like the following (I'm just changing the background color as an example, but you can do whatever you like):

    private void SomethingCalledFromBackgroundThread()
    {
        panel1.Invoke(new DoUpdatePanel(UpdatePanel), Color.Blue);
    }

    private delegate void DoUpdatePanel(Color aColor);

    private void UpdatePanel(Color aColor)
    {
        panel1.BackColor = aColor;
    }

============更新=== ====>

============ Update =======>

@Ash你曲解我的答案。我没有说从内部ProgressChanged调用来调用。 @Jean记住ReportProgress / ProgressChanged正在异步运行 - 这就是为什么你会发现自己制作图像的克隆。如果您在后台线程中使用援引,而不是ReportProgress这不会是必要的。

@Ash you have mischaracterized my answer. I did not say to call Invoke from within ProgressChanged. @Jean keep in mind that ReportProgress/ProgressChanged is being run asynchronously--which is why you find yourself making a clone of your image. This would not be necessary if you use Invoke from within your background thread, rather than ReportProgress.

这篇关于绘制图像的形式从一个单独的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆