Kūrosh
Kūrosh

Reputation: 452

convert bitmapsource to byte array in another thread

i select some image and load them into bitmapimage in the main thread,now i want to save them to sqlserver database in another thread ( BackgroundWorker),But the following error occurs:

The calling thread cannot access this object because a different thread owns it.

Notice : The DataType of target field is varbinary(max)

Sample Code:

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   ---
            }
        }

    }

Upvotes: 1

Views: 1488

Answers (3)

Clemens
Clemens

Reputation: 128060

You would have to Freeze the BitmapSource to make it accessible from other threads, perhaps in AddItem:

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

Note also that it is not necessary to clone the BitmapSource before calling BitmapFrame.Create:

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

Upvotes: 2

Vyacheslav Volkov
Vyacheslav Volkov

Reputation: 4742

You are getting the error because your BitmapSource created on UI thread and you are trying to access its via another thread. To avoid this you need to change the method that converts BitmapSource to bytes to another that don't depend at BitmapSource or convert to bytes in UI thread.

Upvotes: 0

Eugene
Eugene

Reputation: 325

        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

Upvotes: 0

Related Questions