我选择一些图像并将它们加载到主线程中的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 ---
}
}
}
答案 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线程中的字节的字节的方法。