“InvalidOperationException:对象当前正在其他地方使用”在无害的 onpaint 期间?

发布于 2024-12-10 03:20:25 字数 1585 浏览 1 评论 0 原文

由于某种原因,我们收到“InvalidOperationException:对象当前正在其他地方使用”。

在我们的自定义 OnPaint 期间,如下所示(实际上几乎是一行代码的行副本......那里很少)。

我们已登录下面的异常处理程序来检测我们是否以某种方式从非 UI 线程调用 OnPaint...并且这并没有被触发,但我们正在记录该错误(请参阅下面的堆栈跟踪)。

在出现这些错误的机器上,我们还看到来自其他控件的可怕的 Red X of doom(可能在其 OnPaints 周围没有 try/catch)。

它们可能相关,但如果仅从 UI 线程调用此代码,我无法弄清楚可能导致该错误的原因。

有什么想法吗?

这是堆栈跟踪:

System.InvalidOperationException:对象当前正在使用中 其他地方。
位于 System.Drawing.Graphics.CheckErrorStatus(Int32 状态)
在 System.Drawing.Graphics.DrawRectangle(Pen pen, Int32 x、Int32 y、Int32 宽度、Int32 高度)
at System.Windows.Forms.ControlPaint.DrawBorderSimple(图形图形, 矩形边界、颜色颜色、ButtonBorderStyle 样式)
at System.Windows.Forms.ControlPaint.DrawBorder(图形图形, 矩形边界、颜色颜色、ButtonBorderStyle 样式)
at MyUserControl.OnPaint(PaintEventArgs e)

这是类:

public class MyUserControl : UserControl
{
    // Override this to set your custom border color
    protected Color mBorderColor = SystemColors.ControlDarkDark;

    public MyeUserControl()
        : base()
    {
        this.BorderStyle = BorderStyle.None;
        this.Padding = new Padding(1);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        try
        {
            ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, mBorderColor, ButtonBorderStyle.Solid);
        }
        catch (Exception ex)
        {
            // check if we're not on the UI thread, and if not, log it
            // log exception
        }
    }
}

For some reason we are getting "InvalidOperationException: Object is currently in use elsewhere."

during our custom OnPaint, below (that's actually almost a line for line copy of the code... there's that little there).

We have logging in the exception handler below to detect if we're somehow calling OnPaint from a non-UI thread... and that isn't getting tripped, but we are getting that error logged (see stack trace below).

On machines where we're getting these errors, we're also seeing the dreaded Red X of doom from other controls (which presumably don't have a try/catch around their OnPaints).

They're probably related, but I can't figure out what could be causing that error if this code is only called from the UI thread.

Any ideas?

This is the stack trace:

System.InvalidOperationException: Object is currently in use
elsewhere.
at System.Drawing.Graphics.CheckErrorStatus(Int32
status)
at System.Drawing.Graphics.DrawRectangle(Pen pen, Int32
x, Int32 y, Int32 width, Int32 height)
at
System.Windows.Forms.ControlPaint.DrawBorderSimple(Graphics graphics,
Rectangle bounds, Color color, ButtonBorderStyle style)
at
System.Windows.Forms.ControlPaint.DrawBorder(Graphics graphics,
Rectangle bounds, Color color, ButtonBorderStyle style)
at
MyUserControl.OnPaint(PaintEventArgs e)

This is the class:

public class MyUserControl : UserControl
{
    // Override this to set your custom border color
    protected Color mBorderColor = SystemColors.ControlDarkDark;

    public MyeUserControl()
        : base()
    {
        this.BorderStyle = BorderStyle.None;
        this.Padding = new Padding(1);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        try
        {
            ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, mBorderColor, ButtonBorderStyle.Solid);
        }
        catch (Exception ex)
        {
            // check if we're not on the UI thread, and if not, log it
            // log exception
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

客…行舟 2024-12-17 03:20:25

所以,我前一段时间就想到了这个问题,但忘了把答案放在这里。所有遇到问题的客户都有一个共同点 - 他们安装了一个名为 FileOpen 的 adobe 插件。它允许用户阅读加密的 PDF。事实证明,FileOpen 所做的事情(可能是为了阻止加密 PDF 的屏幕捕获或其他内容)通过在 Windows GDI+ 调用(从 .Net OnPaint 方法调用)期间抛出异常来干扰我们的应用程序。在使用 FileOpen 时,他们将我们的应用程序列入白名单,这样他们就不会阻止来自我们应用程序的 GDI+ 调用。

让这个问题变得更加棘手的是,只有在您第一次使用 FileOpen 查看加密的 PDF 后才会发生阻止...因此您可以安装它而不会遇到问题。如果您停止他们的 Windows 服务 FileOpenBroker,它也可以解决问题(大概是该服务正在执行阻止操作)。

只是将其发布在此处,以防其他人看到同样的问题,因为这对我们的工作来说是一个非常令人头痛的问题,并且花了数周时间才弄清楚。

更新:
有一个非常简单的解决方法,即停止 FileOpen 的服务(称为 FileOpenBroker)。您应该能够在 Windows 服务列表中找到它,并将其作为 Windows 任务管理器中的进程找到。一旦该进程停止,它就会停止他们正在做的任何搞砸 GDI+ 的事情,然后您应该能够使用您的程序,直到下次打开加密的 PDF。

已经有一段时间了,所以我不太记得了,但可能需要重新启动才能释放他们在 GDI+ 中设置的任何锁定。我记得我构建了一个批处理文件来启动和停止该服务,以便您可以使用您的程序而无需完全禁用使用 FileOpen 的功能(我认为已安装该文件,因为它正在该计算机上使用)。

我刚刚收到遇到同样问题的其他人联系,所以看起来 FileOpen 还没有解决根本问题 - 他们只是通过将我们的特定应用程序列入白名单来在上面贴上创可贴......公平警告。

So, I figured this out some time ago, but forgot to put the answer on here. All the customers with the problem had a single thing in common - they had installed an adobe plugin called FileOpen. It allows users to read encrypted PDFs. Turns out something FileOpen was doing (presumably to block screen captures of encrypted PDFs or something) was interfering with our application, by throwing exceptions during windows GDI+ calls (which get called from .Net OnPaint methods). In working with FileOpen, they whitelisted our application so that they wouldn't block GDI+ calls from our application.

What made this even more tricky to figure out, is that the blocking only happens after the first time you view an encrypted PDF using FileOpen... so you can have it installed and not experience the problem. If you stop their windows service FileOpenBroker, it also fixes the problem (presumably the service is what is doing the blocking).

Just posting this on here in case anyone else sees the same problem, since this was a huge headache for us at work, and took weeks to figure out.

Update:
There's a pretty easy workaround, which is to stop FileOpen's service, which is called FileOpenBroker. You should be able to find it in the list of windows services and as a process in the windows task manager. Once the process has been stopped, it stops whatever they're doing to screw up GDI+, and then you should be able to use your program until the next time you open an encrypted PDF.

It's been a while, so I don't remember for sure, but it's possible a reboot was necessary to release whatever locks they put in GDI+. I remember I built a batch file to start and stop the service, so that you could use your program without completely disabling the ability to use FileOpen (which I presume is installed because it's in use on that computer).

I just got contacted by someone else hitting this same problem, so it seems like FileOpen hasn't fixed the root problem - they only put a band-aid on it by whitelisting our particular application... fair warning.

倒数 2024-12-17 03:20:25

此博客文章解释了错误消息:

http://msmvps.com/blogs/peterritchie/archive/2008/01/28/quot-object-is-currently-in-use-elsewhere-quot-error.aspx

我但无法将其与您发布的代码相匹配,该表单上是否还有其他图形操作正在进行?

另外,我可以想象一个非 UI 线程成功执行此代码,同时 UI 线程尝试但失败,导致 UI 线程上发生错误。

This blog post explains the error message:

http://msmvps.com/blogs/peterritchie/archive/2008/01/28/quot-object-is-currently-in-use-elsewhere-quot-error.aspx

I can't match that with the code you posted though, is there any other graphics operations going on on that form?

Also I could imagine a non-UI thread executing this code successfully, and at the same time the UI thread trying and failing, causing the error to occur on the UI thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文