Reputation: 452
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
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
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
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