You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.Net Background Worker代码报错:Object is currently in use elsewhere

解决思路及代码修正

问题根源

异常是因为后台线程在修改Destination Bitmap的同时,UI线程通过ProgressChanged事件绑定该Bitmap到PictureBox1.Image,两个线程同时访问同一个Bitmap资源,引发资源占用冲突。

具体解决方案

  • 分离UI预览与后台处理的资源
    不要在ProgressChanged中直接绑定正在修改的Destination,仅在该事件中更新进度文本,待后台处理完成后,再将最终的Destination赋值给PictureBox。

  • 优化图像操作性能(可选但推荐)
    GetPixel和SetPixel是低效的像素操作方法,改用LockBits直接操作内存,既能提升处理速度,也能减少线程间资源竞争的概率。

修改后的代码示例

修正后台工作者与进度更新逻辑

Private Sub BGWProcess_DoWork(sender As Object, e As DoWorkEventArgs) Handles BGWProcess.DoWork
    For Y = 0 To hgt
        If BGWProcess.CancellationPending Then 
            e.Cancel = True
            Exit Sub
        End If
        For X = 0 To wid
            Destination.SetPixel(X, Y, Source.GetPixel(X, Y))
        Next
        BGWProcess.ReportProgress(Y)
    Next
    ' 处理完成后将Destination作为结果传递
    e.Result = Destination
End Sub

Private Sub BGWProcess_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BGWProcess.ProgressChanged
    ' 仅更新进度文本,不操作Bitmap
    TxtProgress.Text = e.ProgressPercentage.ToString
End Sub

Private Sub BGWProcess_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BGWProcess.RunWorkerCompleted
    If Not e.Cancelled AndAlso e.Error Is Nothing Then
        ' 处理完成后再绑定到PictureBox
        PictureBox1.Image = CType(e.Result, Bitmap)
    End If
End Sub

用LockBits优化像素操作(推荐)

如果图像尺寸较大,替换GetPixel/SetPixel为LockBits能大幅提升效率,同时降低线程冲突风险:

Private Sub BGWProcess_DoWork(sender As Object, e As DoWorkEventArgs) Handles BGWProcess.DoWork
    ' 锁定Source和Destination的内存
    Dim srcData = Source.LockBits(New Rectangle(0, 0, Source.Width, Source.Height), Imaging.ImageLockMode.ReadOnly, Source.PixelFormat)
    Dim destData = Destination.LockBits(New Rectangle(0, 0, Destination.Width, Destination.Height), Imaging.ImageLockMode.WriteOnly, Destination.PixelFormat)

    Dim stride = srcData.Stride
    Dim byteCount = stride * Source.Height
    Dim srcBytes(byteCount - 1) As Byte
    Dim destBytes(byteCount - 1) As Byte

    ' 复制源图像内存到数组
    System.Runtime.InteropServices.Marshal.Copy(srcData.Scan0, srcBytes, 0, byteCount)
    
    ' 示例直接复制像素,可在此添加自定义处理逻辑
    Array.Copy(srcBytes, destBytes, byteCount)

    ' 将处理后的数组复制回目标Bitmap
    System.Runtime.InteropServices.Marshal.Copy(destBytes, 0, destData.Scan0, byteCount)

    ' 解锁内存
    Source.UnlockBits(srcData)
    Destination.UnlockBits(destData)

    e.Result = Destination
End Sub

内容的提问来源于stack exchange,提问作者zomalaja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:22:18