将bitmapsource转换为另一个线程中的字节数组

时间:2013-05-07 04:12:23

标签: c# wpf multithreading

我选择一些图像并将它们加载到主线程中的bitmapimage中,现在我想将它们保存到另一个线程(BackgroundWorker)中的sqlserver数据库中,但发生以下错误:

调用线程无法访问此对象,因为另一个线程拥有它。

注意:目标字段的DataType是varbinary(max)

示例代码:

class Class1
    {
        private List<BitmapSource> Items;
        public Class1()
        {
            this.Items = new List<BitmapSource>();
        }
        public void AddItem(BitmapSource bs)
        {
            this.Items.Add(bs);
        }
        public void Save()
        {
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += bw_DoWork;
            bw.RunWorkerCompleted += bw_RunWorkerCompleted;
            bw.RunWorkerAsync(this.Items);
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            throw new NotImplementedException();
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            MyBLL bl = new MyBLL();
            bl.Save(e.Argument as List<BitmapSource>);
        }

    }

public class MyBLL
    {

        public byte[] ConvertBitmapSourceToByteArray(BitmapSource BS)
        {
            if (BS == null)
            {
                return new byte[] { };
            }
            using (MemoryStream ms = new MemoryStream())
            {
                JpegBitmapEncoder jbe = new JpegBitmapEncoder();

                jbe.Frames.Add(BitmapFrame.Create(BS.Clone()));
                jbe.Save(ms);
                return ms.GetBuffer();
            }
        }

        public void Save(List<BitmapSource> _items)
        {
            foreach (BitmapSource item in _items)
            {
                ---  insert  ConvertBitmapSourceToByteArray(item) to DataBase   ---
            }
        }

    }

3 个答案:

答案 0 :(得分:2)

您必须Freeze BitmapSource才能从其他线程访问它,可能在AddItem中:

public void AddItem(BitmapSource bs)
{
    bs.Freeze();
    this.Items.Add(bs);
}

另请注意,在调用BitmapFrame.Create之前无需克隆BitmapSource:

jbe.Frames.Add(BitmapFrame.Create(BS));

答案 1 :(得分:0)

        BackgroundWorker worker = new BackgroundWorker();
        Image yourImg = new Bitmap(1,1);
        worker.DoWork += new DoWorkEventHandler((o,arg)=>{
            Image img = arg.Argument as Image;
            //Do whatever you want with your image
        });            
        worker.RunWorkerAsync(yourImg);//pass your image as a parameter to your sub-thread

答案 2 :(得分:0)

您收到错误是因为您在UI线程上创建的BitmapSource并且您正尝试通过另一个线程访问它。为避免这种情况,您需要将BitmapSource转换为另一个不依赖于BitmapSource或转换为UI线程中的字节的字节的方法。