我抖動BackgroundWorker線程中的圖像,並且需要在完成圖像處理後更新UI。我需要更新的圖像與DitherWorker存在於同一個類中。如何傳遞BitmapSource以避免發生指出的錯誤?從BackgroundWorker返回一個對象
public void DitherWorker()
{
double scalebox = Double.Parse(myWindow.scaleBox.Text);
int slider = (int)myWindow.convolutionBiasSlider.Value;
BitmapSource final = null;
ditherobj output = new ditherobj(scalebox, originalImage, slider);//.Get_Halftone();
worker = new BackgroundWorker();
worker.WorkerSupportsCancellation = true;
worker.DoWork += delegate(object s, System.ComponentModel.DoWorkEventArgs args)
{
ditherobj dob = (ditherobj)args.Argument;
Binarize bn = new Binarize(dob.scalebox, dob.localbms, dob.slider);
BitmapSource bms = (BitmapSource)bn.Get_Halftone();
final = bms;
args.Result = new ditherobj(0,null,0,bms);
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
ditherobj dob = (ditherobj)args.Result;
image1.Source = dob.localbms; //ERROR. The calling thread cannot access this object because another thread owns it
myWindow.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(() =>
{
myWindow.activityBar.IsBusy = false;
}));
};
worker.RunWorkerAsync((ditherobj)output);
}
public class ditherobj
{
public double scalebox;
public BitmapSource localbms;
public BitmapImage localbmi;
public int slider;
public ditherobj(double scalebox, BitmapImage localbmi, int slider, BitmapSource bms = null)
{
this.scalebox = scalebox;
this.slider = slider;
if (bms == null)
{
BitmapImage test = localbmi.Clone();
localbms = (BitmapSource)test;
}
else
localbms = bms;
}
}
問題解決了。在傳遞之前,BitmapSource必須在後臺線程中凍結。下面是最終comented代碼:
BackgroundWorker worker;
public void DitherWorker()
{
double scalebox = Double.Parse(myWindow.scaleBox.Text); //get values from UI for the job
int slider = (int)myWindow.convolutionBiasSlider.Value;
DitherSettings output = new DitherSettings(scalebox, originalImage, slider); //create holder object to be passed to BackgroundWorker
worker = new BackgroundWorker();
worker.DoWork += delegate(object s, System.ComponentModel.DoWorkEventArgs args)
{
DitherSettings ds = (DitherSettings)args.Argument; //cast argument as our holder object
Binarize bn = new Binarize(ds.scalebox, ds.localbms, ds.slider); //create object to do our work
BitmapSource bms = (BitmapSource)bn.Get_Halftone(); //do work
bms.Freeze(); //freeze resulting BitmapSource so it can be utilized elsewhere
args.Result = new DitherSettings(0,null,0,bms); //create new object with resulting BitmapSource
};
worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
DitherSettings ds = (DitherSettings)args.Result; //get object with our BitmapSource
if (image1.Dispatcher.CheckAccess())
this.image1.Source = ds.localbms; //update class image
myWindow.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(() =>
{
myWindow.activityBar.IsBusy = false; //Update UI control
}));
};
worker.RunWorkerAsync((DitherSettings)output);
}
public class DitherSettings
{
public double scalebox;
public BitmapSource localbms;
public BitmapImage localbmi;
public int slider;
public DitherSettings(double scalebox, BitmapImage localbmi, int slider, BitmapSource bms = null)
{
this.scalebox = scalebox;
this.slider = slider;
if (bms == null)
localbms = (BitmapSource)localbmi;
else
localbms = bms;
}
}
什麼是'ditherobj'?線程所有權和所有權轉移的概念不是.NET的核心;如果這是第三方庫,您使用的是哪個庫?或者這是你的班級? – Jacob
一個容易傳遞值的簡單對象。編輯帖子以顯示此內容。 – PhilJ
爲什麼'ditherobj'類/ struct沒有命名爲'DitherSettings'? –