翼度科技»论坛 编程开发 .net 查看内容

BitMap对象当前正在其他地方使用?加锁也没用?

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
最近在工作中遇到一个问题,就是我有多个线程会调用bitmap对象,运行的时候报错,对象当前正在其他地方使用。第一反应肯定是加锁啊,于是我就在每个用到bitmap的地方都加了锁,但是运行之后依然报这个错

 
 测试代码如下
  1. using System;
  2. using System.Drawing;
  3. using System.Threading;
  4. using System.Windows.Forms;
  5. namespace BitMapLockTest
  6. {
  7.     public partial class Form1 : Form
  8.     {
  9.         private Bitmap testBitmap;
  10.         private static readonly object obj = new object();
  11.         public Form1()
  12.         {
  13.             InitializeComponent();
  14.         }
  15.         private void Form1_Load(object sender, EventArgs e)
  16.         {
  17.             testBitmap = new Bitmap(100, 100);
  18.             Thread th = new Thread(DrawBackGround);
  19.             th.IsBackground = true;
  20.             th.Start();
  21.         }
  22.         private void DrawBackGround()
  23.         {
  24.             while (true)
  25.             {
  26.                 lock (obj)
  27.                 {
  28.                     Graphics g = Graphics.FromImage(testBitmap);
  29.                     g.Clear(Color.White);
  30.                     g.Dispose();
  31.                 }
  32.             }
  33.         }
  34.         private void button1_Click(object sender, EventArgs e)
  35.         {
  36.             lock (obj)
  37.             {
  38.                 Graphics g = Graphics.FromImage(testBitmap);
  39.                 g.FillRectangle(new SolidBrush(Color.FromArgb(100, 200, 2)), new Rectangle(new Point(0, 0), new Size(20, 20)));
  40.                 g.Dispose();
  41.                 Updatepic(testBitmap);
  42.             }
  43.         }
  44.         private void Updatepic(Bitmap bitmap)
  45.         {
  46.             if (pictureBox1.InvokeRequired)
  47.             {
  48.                 Invoke(new Action<Bitmap>(Updatepic), bitmap);
  49.             }
  50.             else
  51.             {
  52.                 lock (obj)
  53.                 {
  54.                     pictureBox1.Image = bitmap;
  55.                 }
  56.             }
  57.         }
  58.     }
  59. }
复制代码
网上也有之类的问题,都是告诉我,不应该多线程使用bitmap对象,如果有需求,可以用bitmap.clone(). 
改了下
  1.    private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             lock (obj)
  4.             {
  5.                 Graphics g = Graphics.FromImage(testBitmap);
  6.                 g.FillRectangle(new SolidBrush(Color.FromArgb(100, 200, 2)), new Rectangle(new Point(0, 0), new Size(20, 20)));
  7.                 g.Dispose();
  8.                 Updatepic((Bitmap)testBitmap.Clone());
  9.             }
  10.         }
复制代码
OK,不报错了。但我的疑问没解除啊
你得告诉我为啥锁不住啊?难道是lock(obj)写的不对?那我换成 lock (testBitmap)总行了吧,依然报错。。。
后来我想了下。终于想明白了
问题出来这里
pictureBox1.Image = bitmap;
bitmap是个引用对象,把他赋值给pictureBox1的Image属性之后。pictureBox1所在的UI线程就一直保持了对bitmap对象的引用。所以别的线程加了锁也没用,依然会报错。
用clone方法复制对象的根本原因,就是避免了UI对原对象的引用。
我以为在所有引用bitmap的地方都加了锁不应该有问题了,却忘了。UI线程对其的引用。
低级错误。。。
 

来源:https://www.cnblogs.com/flylittlebaby/archive/2023/03/30/17271698.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具