位图区域已被锁定,多线程环境

2023-12-02

我正在使用一个通过多个线程调用主函数的 API。我试图通过该函数访问另一个类中的位图并从中写入,但即使将其设置为使用完全不同的对象实例后,我也遇到了 InvalidOperationException:位图区域已被锁定。

我尝试在主函数和调用 Bitmap.LockBits(...) 的位置锁定代码。是的,当我完成后,UnlockBits 就会被调用。

    /* Part of Class B */
    public Surface imageSurface //Surface is a field of pixels, more or less.
    {
        get
        {
            if (_CurrImage != null && _imageSurface == null)
            {

                _imageSurface = Surface.CopyFromBitmap(_CurrImage);
                return Surface.CopyFromBitmap(_imageSurface.CreateAliasedBitmap());
            }
            else
            {
                Surface clearPixel = new Surface(1, 1);
                clearPixel[0, 0] = ColorBgra.FromBgra(255, 255, 255, 0);
                return clearPixel;
            }
        }
    }
    /* the "main" function, Class A */
    public override void Render(ClassBPrototype parameters, ...)
    {
        ClassB token = (ClassB)parameters; // Here we go again~!
        ...
        Surface ourSurface = dstArgs.Surface;
        if (token.imageSurface.Size != null)
        {
            ourSurface = token.imageSurface;
        }

        lock(typeof(ClassA))
        {
            for (int lRectangleIndex = ...)
            {
                Rectangle lRectangle = rois[lRectangleIndex];

                for (int y = ...)
                {
                    surfaceY = (ourSurface.Height / 2) - (y - (int)CenterY);

                    for (int x = ...)
                    {
                        surfaceX = (ourSurface.Width / 2) - (x - (int)CenterX);
                        if (surfaceX >= 0 && surfaceX < ourSurface.Width && surfaceY >= 0 && surfaceY < ourSurface.Height)
                        {
                            dstArgs.Surface[x, y] = ourSurface[surfaceX, surfaceY];
                        }
                        else
                        {
                            dstArgs.Surface[x, y] = ColorBgra.FromBgra(255, 255, 255, 0);
                        }

                    }
                }
            }
        }
    }

问题很可能是共享资源(位图)不受代码示例中的锁保护。锁需要包裹两个LockBits and UnlockBits呼吁有效防止同时访问Bitmap实例。

在这种情况下,我建议使用实际的Bitmap实例作为锁对象,因为这是需要防止来自不同线程的同时访问的对象。

锁定typeof(ClassA)仅建议在静态方法内使用锁时。

请注意,锁是互斥锁,当一个线程获得锁时,其他线程将被挂起。如果大部分时间都花在锁内,则多线程不会带来或很少有并行化的好处。

如果发生异常,锁将根据锁构造的设计被释放,而UnlockBits方法通常不会被调用。如果可以抛出并捕获异常,我建议调用UnlockBits来自finally 块的方法。像这样的事情:

private Bitmap _bitmap;
public void foo()
{
    lock (_bitmap)
    {
        BitmapData data;
        try
        {
            data = _bitmap.LockBits(area, ImageLockMOde.ReadOnly, pixelFormat);
            UseBitmapData(data);
        }
        finally
        {
            _bitmap.UnlockBits(data);
        }
    }
}

该逻辑也可以封装在它自己的类中,实现 IDisposable 接口,从而实现强大的功能using要使用的构造。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

位图区域已被锁定,多线程环境 的相关文章

随机推荐

  • 应用程序进入后台后每 n 分钟获取用户位置

    我正在努力实施中给出的建议这个帖子 不幸的是 我不清楚这些步骤 我尝试实施这些建议 但即使在启动和停止 locationServices 后 backgroundTimeRemaining 仍继续减少 我是这样开发的 void applic
  • Android 是否按升序或降序覆盖资源文件?

    Android 有各种文件夹来设置其资源 例如 values small values normal values large drawable mdpi drawable hdpi drawable xhdpiAndroid 如何从这些文
  • 循环遍历 Excel 中某个范围的每一行

    这是我确信有一个内置函数的事情之一 而且我很可能在过去被告知过 但我正在挠头去记住它 如何使用 Excel VBA 循环遍历多列范围的每一行 我一直在搜索的所有教程似乎都只提到在一维范围内工作 Dim a As Range b As Ran
  • 运行作业时的参数解释

    h host1 example com code Get WmiObject Class Win32 ComputerSystem Namespace root cimv2 ComputerName h timeout 5 jobstate
  • 在 Foreach 循环中递增变量并使用它-SSIS

    我有一个包 我正在使用 foreach 循环来循环数据库 我正在传递一个字符串 它会循环遍历所有数据库 到这里一切都很完美 我想要实现的是 对于它循环的每个数据库 它应该将变量增加 1 假设我必须循环遍历总共 5 个数据库 包级变量 myv
  • 等待 Firebase 检索数据[重复]

    这个问题在这里已经有答案了 我想构建一个返回a的方法childFirebase 中的值 我尝试做这样的事情 public String getMessage root child MessagesOnLaunch child Message
  • 通过RedBean批量插入mysql

    如何运行以下sqlRedBean INSERT INTO tbl name a b c VALUES 1 2 3 4 5 6 7 8 9 我应该使用循环还是RedBean支持批量插入 RedBeanPHP 的创建者在这里 RedBeanPH
  • 在 Adob​​e AIR for iOS 中获取唯一标识符(MAC 地址、UDID 等)

    我正在尝试在适用于 Android 和 iOS iPad 2 的 Adob e AIR 应用程序中获取用户设备网络适配器的 MAC 地址 在 Android 中它可以正常工作 但在 iOS 中却不能 这是我正在使用的代码 var vNetw
  • 从unittest.TestCase切换到tf.test.TestCase后的幻像测试

    以下代码 class BoxListOpsTest unittest TestCase Tests for common bounding box operations
  • Sparklyr:如何将列表列分解为 Spark 表中自己的列?

    我的问题与中的问题类似here 但我在实现答案时遇到问题 并且我无法在该线程中发表评论 因此 我有一个包含嵌套数据的大 CSV 文件 其中包含由空格分隔的 2 列 假设第一列是 Y 第二列是 X X 列本身也是一个逗号分隔值 21 66 2
  • OS X Yosemite 中 setenv 和 getenv 的奇怪行为

    当我设置环境变量时 launchctl setenv FOO test 我可以通过以下方式获取值 launchctl getenv FOO 这返回我 测试 但是一个简单的 echo FOO 不替换 结果为空 在同一航站楼以及新航站楼中 背景
  • 全局变量被炼金术打破了?

    看起来Adobe炼金术没有运行全局构造函数 这是一些简单的测试代码 include
  • 更改通过 JsonExtensionData 加载的数据的键名称[重复]

    这个问题在这里已经有答案了 我有一个由系统数据和用户条目混合而成的 JSON 如下所示 Properties Type A Name aaa lorem ipsum 7 1 Type B Name bbb sit amet XYZ Type
  • 根据文件扩展名验证文件

    我从 Java 队列中获取文件 它们可能具有以下格式 docx pdf doc xls xlsx txt rtf 阅读它们的扩展名后 我想验证它们是否确实是这些类型的文件 例如 我收到一个文件并检查其扩展名是否为 xls 之后 我想检查它是
  • 在打印机兼容的设备上下文中调用 Windows SelectObject 返回 NULL

    最近的 Windows 10 更新 可能也是神秘的 KB4577586 似乎已经产生了引起调用的效果选择对象使用位图句柄作为参数 在打印机兼容的设备上下文中执行时返回 NULL 相关行可以在这个中看到位图打印示例 它在早期的 Windows
  • 从字节码解析类名

    是否可以从类源代码形成的字节码中挖掘类名称 情况是这样的 我从某个地方远程获取类字节码 它来自哪里并不重要 为了使用类加载器有效地加载该类 我还需要类名 对吗 如果您只需要类名 那么您自己解析类文件的开头可能会更容易 而不是为此目的添加用于
  • R 语言:使用 ff 包计算“group by”或拆分时出现问题

    我对 R 几乎是新手 很抱歉如果我提出一些基本问题 但我找不到这个 简单 问题的解决方案 我有一个患者数据库 大数据库 2500 万行 14 列 每个 id 有几行 例如以下结构 id birth date treatment date t
  • processing.js 加载外部文件

    我想将我的processing js 代码分割成几个文件 但我不知道如何分割 我尝试做
  • Flow Router 不适用于 ObjectID。有什么解决办法吗?

    我正在尝试在我的 Meteor 应用程序中构建路线 路由工作得很好 但使用路由路径从数据库获取信息却不起作用 我用这个创建我的页面特定路线 FlowRouter route level id 这条路线将我毫无问题地带到相关模板 然后我想从数
  • 位图区域已被锁定,多线程环境

    我正在使用一个通过多个线程调用主函数的 API 我试图通过该函数访问另一个类中的位图并从中写入 但即使将其设置为使用完全不同的对象实例后 我也遇到了 InvalidOperationException 位图区域已被锁定 我尝试在主函数和调用