在我的程序中有一个 BackgroundWorker 类将图像预加载到 BitmapImage 对象。我需要将该预加载的图像传递给主应用程序 (WPF),在那里它将被复制到另一个 BitmapImage 对象。这似乎有效,但是,当我尝试时
imgViewer.Source = imgNext; //imgNext is a main app copy of the preloaded image
发生错误意味着该对象 (imgNext) 由另一个线程拥有并且无法使用。
有什么想法可以摆脱它并使代码正常工作吗?
谢谢大家的回答!
事实上,我设法通过在 App
类中创建静态 BitmapImage
来解决这个问题。
在使用它之前,我会这样做
App.iNext = null;
然后我加载实际图像并将其卡住,这样这个静态属性就可以从任何地方访问。当循环重复多次时,分配 null 可防止出现“对象已卡住”错误。
当然,还有很多管理单个 BGW 实例、排队任务等的工作。
(目前我正在使用也在我的程序中定义的 ImagesContainer 类,它有两个 BitmapImage 属性。我用它来接收来自 backgroundworker 的预加载图像。)
imgNext 是 MainWindow 中定义的公共(public)变量。 (主线程)
void bwImgLoader_DoWork(object sender, DoWorkEventArgs e)
{
backgrLoadNextPrevList list = e.Argument as backgrLoadNextPrevList;
ImagesContainer result = new ImagesContainer();
if (list.HasNextPath) result.imgPrev = PrepareImage(list.NextPath);
if (list.HasPrevPath) result.imgNext = PrepareImage(list.PrevPath);
e.Result = result;
}
void bwImgLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
ImagesContainer result = e.Result as ImagesContainer;
if (result.imgNext != null)
{
setNextDelegate s = new setNextDelegate(setNext);
object[] t = { result.imgNext };
imgNext.Dispatcher.Invoke(s, t);
}
// do not take into account this line, just ignore it.
//if (result.imgPrev != null) imgPrev = result.imgPrev;
}
public void setNext(BitmapImage b)
{
imgNext = b;
}
public delegate void setNextDelegate(BitmapImage b);
卡住位图图像仅对第一次后台加载有帮助(请参阅下面答案下的评论)。当我第二次调用 BackgroundWorker 时,出现对象被卡住且无法修改的错误。有办法解冻吗?
或者,有没有什么方法可以将数据从一个线程复制到另一个线程而不复制线程的属性?
已更新
谢谢大家的回答!
事实上,我设法通过在 App
类中创建静态 BitmapImage
来解决这个问题。
在使用它之前,我会这样做
App.iNext = null;
然后我加载实际图像并将其卡住,这样这个静态属性就可以从任何地方访问。当循环重复多次时,分配 null 可以防止错误。
当然,还有很多管理单个 BGW 实例、排队任务等的工作。
但这些努力是值得的 - 我的表现提高了 125%!!!谢谢大家!
最佳答案
BitmapImage
是Freezable
,因此您可以在加载后对其进行Freeze()
。这将允许从任何线程进行访问。
关于c# - WPF 和 backgroundworker 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4617292/