1

我选择了一些图像并将它们加载到主线程中的位图图像中,现在我想将它们保存到另一个线程(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   ---
            }
        }

    }
4

3 回答 3

2

您必须冻结BitmapSource 以使其可以从其他线程访问,可能在 AddItem 中:

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

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

jbe.Frames.Add(BitmapFrame.Create(BS));
于 2013-05-07T09:41:41.440 回答
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
于 2013-05-07T05:14:50.880 回答
0

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

于 2013-05-07T06:01:53.733 回答