1

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

    }
2
  • Can you provide the code? Commented May 7, 2013 at 4:37
  • thanks . i add a sample code to my question Commented May 7, 2013 at 6:00

3 Answers 3

2

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));
Sign up to request clarification or add additional context in comments.

Comments

0

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.

4 Comments

ok ,but how can i convert BitmapSource to bytes to that don't depend at BitmapSource ??? i dont want to convert bitmapsource to bytes in the ui thread
Where do you get the BitmapSources?
i get a image file of type BitmapSource from a custom class and bind it to ui , then pass it to AddItem method of Class1.
It would be better if a custom class returns an image as Stream (or other format that don't depend from UI) and then you can convert it to the BitmapSource to display in UI and use the Stream for convert.
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

1 Comment

thanks but i want to pass a collection of BitmapSource that binded to the UI.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.