“对象当前在其他地方使用”,但它在哪里使用,谁在使用它?

"Object is currently in use elsewhere", but where is it in use, and who is using it?

提问人:Tim Makins 提问时间:1/12/2023 最后编辑:Tim Makins 更新时间:1/13/2023 访问量:104

问:

有很多答案描述了为什么会发生这个错误,但我找不到任何答案来解释如何确定 (a) 哪个例程失败,(b) 我们在谈论哪个对象,以及 (c) 哪个其他代码位正在使用该对象。通常我们至少会得到一个行号,但出于某种原因,这个错误想让我猜测。有什么想法吗?(这是一个运行着多个线程的大型程序。

    System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>MyLargeProgram.exe</AppDomain><Exception><ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>Object is currently in use elsewhere.</Message><StackTrace>   at System.Drawing.Image.get_Width()
       at System.Drawing.Image.get_Size()
       at System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode mode)
       at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
       at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
       at System.Windows.Forms.Control.WmPaint(Message&amp;amp; m)
       at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)</StackTrace><ExceptionString>System.InvalidOperationException: Object is currently in use elsewhere.
       at System.Drawing.Image.get_Width()
       at System.Drawing.Image.get_Size()
       at System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode mode)
       at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
       at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
       at System.Windows.Forms.Control.WmPaint(Message&amp;amp; m)
       at System.Windows.Forms.Control.WndProc(Message&amp;amp; m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp;amp; m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp;amp; m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)</ExceptionString></Exception></TraceRecord>

应用程序创建一个大图像,该图像最终显示在 PictureBox 上。最终图像由线程分 4 个阶段从其他 4 个图像创建,线程复制其中一个现有图像,对其进行更改,然后再次将其保存到该图像。如果图像在其他地方使用,则有一些标志可以阻止图像被访问。最终线程获取第 4 个图像,对其进行更改,然后将修改后的图像的克隆设置为 PictureBox 图像。

    SyncLock bm
        PbWM.Image?.Dispose()
        PbWM.Image = CType(bm.Clone, Bitmap)
    End SyncLock

我以为我已经使用了足够的 SyncLock 和标志,但也许没有。我不知道为什么System.Transactions会出现在那里。我不是在导入它。


关于锁定的另一个问题:这是我用来替换图像内容的方法。有没有更好的方法?

    ' The Thread enters with Bitmap bm1..

    ' I make a working copy of bm1
    Using bm0 As Bitmap = CType(bm1.Clone, Bitmap)
        Using gr As Graphics = Graphics.FromImage(bm)
            ' Some image drawing is done here
        End Using

        SyncLock bm
            ' Replace bm1 with the altered image
            bm1 = CType(bm0.Clone, Bitmap)
        End SyncLock
    End Using

也许这是最好的方法?

    ' The Thread enters with Bitmap bm1..

    ' I make a working copy of bm1
    Using bm0 As Bitmap = CType(bm1.Clone, Bitmap)
        Using gr As Graphics = Graphics.FromImage(bm)
            ' Some image drawing is done here
        End Using

        Dim thisLock As New Object
        SyncLock thisLock
            ' Replace bm1 with the altered image
            bm1 = CType(bm0.Clone, Bitmap)
        End SyncLock
    End Using

还是这个?

    ' The Thread enters with Bitmap bm1..

    ' I make a working copy of bm1
    Using bm0 As Bitmap = CType(bm1.Clone, Bitmap)
        Using gr As Graphics = Graphics.FromImage(bm)
            ' Some image drawing is done here
        End Using

        Dim thisLock As New Object
        SyncLock thisLock
            ' Replace bm1 with the altered image
            bm1 = New Bitmap(bm0)
        End SyncLock
    End Using
vb.net 多线程

评论

0赞 Panagiotis Kanavos 1/12/2023
应用程序代码有什么作用,为什么会出现在这里?应用程序是否尝试通过在 PictureBox 对象上呈现来创建图像?这些不是线程安全的,用于在屏幕上显示数据,而不是生成图像文件。它们使用有限的 GDI 资源进行屏幕呈现。使用像 ImageSharp 这样的图像处理库要便宜得多,速度也快得多System.Transactions
0赞 Olivier Jacot-Descombes 1/12/2023
我们需要看到产生此错误的代码。
0赞 Tim Makins 1/12/2023
@PanagiotisKanavos - 感谢您的回答。我已经用更多信息修改了我的问题。我不知道 ImageSharp。
0赞 Tim Makins 1/12/2023
@OlivierJacot-Descombes - 问题是我不知道是哪位代码产生了错误,所以我无法向您展示它!这就是我发布问题的原因:我很想知道哪位代码产生了错误:通常错误会告诉您行号,或者停止并指向该部分,但在这种情况下,它不会。
1赞 Jimi 1/12/2023
阅读 DependentTransaction 和使用 DependentTransaction 管理并发的“备注”部分 -- 如果需要锁,请在该锁上创建一个 and 锁,而不是例如,您正在处理的对象ObjectMe

答: 暂无答案