2016-11-15 150 views
0

我正在使用工作线程将.png图像(从路径字符串)加载到全局PictureBox2对象中,然后退出_RunWorkerCompleted以在名为processpic2的方法中使用PictureBox2的宽度和高度进行其他工作。一切正常,直到第5或第6张图像被添加到PB。这一点,在processpic2方法中,由于PictureBox2的图像属性评估为无,所以抛出异常。PictureBox停止添加图像

为什么PB会在一段时间后停止拍照?

Public Class Form1 
Public WithEvents BackgroundWorker1 As New System.ComponentModel.BackgroundWorker 

Private Sub BackGroundworker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    Dim args As ArgumentType = e.Argument 
    PictureBox2.Image = Nothing 
    PictureBox2.Invalidate() 
    Dim img As Image 
    Using str As Stream = File.OpenRead(args._pathstr) 
     img = Image.FromStream(str) 
    End Using 
    PictureBox2.Image = img 
    e.Result = "done" 
End Sub 

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _Handles BackgroundWorker1.RunWorkerCompleted 
    'Called when the BackgroundWorker is completed. 
    processpic2() 
End Sub 

Sub btnLoadPicture(pathstr) 
    Dim args As ArgumentType = New ArgumentType() 
    args._pathstr = pathstr 
    BackgroundWorker1.RunWorkerAsync(args) 
End Sub 

Sub processpic2() 
    If PictureBox2.Image Is Nothing Then MsgBox("Image is Nothing") 
End Sub 
+1

不要从后台工作进程的UI元素,这就是为什么...使用委托和调用...图片框是在不同的线程比背景的工作人员... – Codexer

+0

我不认为我需要回答这个为什么评论。看看你正在使用的UI控件的调用会让你朝着正确的方向前进。如果您仍然需要帮助,请更新您的问题,我们很乐意为您提供帮助。 – Codexer

+1

我同意Zaggler。你可能会在'RunWorkerCompletedEventArgs'(即'e.Result')中返回加载的图像,并在RunWorkerCompleted中设置'PictureBox.Image'。 – SSS

回答

1

BackgroundWorker整点要做后台工作。对UI进行更改与后台工作完全相反。这是前台工作。如果您的任务是清除PictureBox的当前内容,请从文件加载图像,然后显示该图像,但只有中间步骤是后台工作,所以只有中间步骤应在DoWork事件处理程序中完成。第一步应在拨打RunWorkerAsync之前完成,最后一步应在RunWorkerCompleted事件处理程序中完成。

说了这么多,在这种情况下为什么要使用BackgroundWorker?为什么不简单地调用PictureBox本身的LoadAsync方法?

+0

谢谢 - 不知道'PictureBox'的'LoadAsync'方法,所以会研究。有一件事是肯定的,图像大约是600 x 400像素的.png,即使设置了“PictureBox1.Image = Nothing”,图片框在加载和查看大约5-8张图像之后往往会挂起。似乎有些记忆内容正在被填满或什么东西。 'PictureBox1.Invalidate'和'PictureBox1.Image = Nothing'不能帮助消除这个特点。 – wrtsvkrfm

+0

'图像'是一个可丢弃的物体。如果你正在创建一个Image对象并将它分配给一个PictureBox的Image属性,那么当你完成它时,你应该在该Image对象上调用Dispose。 – jmcilhinney

0

解决方案 - 得益于建议收到,而我在MSDN上找到有关的PictureBoxLoadAsync方法下面的代码解决了这个问题:

PictureBox2.Image = Nothing 

PictureBox2.WaitOnLoad = False 

' Load the image asynchronously. 
PictureBox2.LoadAsync(pathstr)