C# 使用TPL向图像控件呈现程序图标
嗨,我正在尝试创建一个交互性。在后台加载程序图标的行为。下面是代码,但它给了我调用线程无法访问此对象的消息,因为它是另一个线程拥有的C# 使用TPL向图像控件呈现程序图标,c#,wpf,behavior,task-parallel-library,C#,Wpf,Behavior,Task Parallel Library,嗨,我正在尝试创建一个交互性。在后台加载程序图标的行为。下面是代码,但它给了我调用线程无法访问此对象的消息,因为它是另一个线程拥有的 protected override void OnAttached() { base.OnAttached(); if (!string.IsNullOrEmpty(Url)) { Icon ico = Icon.ExtractAssociatedIcon(Url);
protected override void OnAttached()
{
base.OnAttached();
if (!string.IsNullOrEmpty(Url))
{
Icon ico = Icon.ExtractAssociatedIcon(Url);
if (ico != null)
{
taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => {
MemoryStream ms = new MemoryStream();
ico.ToBitmap().Save(ms, ImageFormat.Png);
ms.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
return bi;
}).ContinueWith((t) => AssociatedObject.Source = t.Result, taskScheduler);
}
}
}
尽管您使用的是CurrentSynchronizationContext,但如果必须在图标的
调度程序上运行,请尝试一下
ico.Dispatcher.BeginInvoke(
new Action(
() =>
{
ico.ToBitmap().Save(ms, ImageFormat.Png);
///rest of the code that uses `ms`.
}));
建议:为什么不使用优先级绑定
和绑定.IsAsync
来缓慢加载图像
WPF对象(从其派生的任何对象)是线程仿射对象——通常它们只能在创建它们的线程上使用。这包括对象。如果在后台线程上创建BitmapImage,则只能从该后台线程使用它——这意味着UI线程在尝试显示位图时会出错
但是,BitmapImage从。Freezable有一个方法可以使实例只读。并根据MSDN上的“”:
冻结的Freezable也可以跨线程共享,而未冻结的Freezable则不能
因此,如果您添加对bi.Freeze()的调用
在您从后台任务返回图像之前,您应该能够从UI线程成功使用图像。谢谢。。我今天学到了一些新东西……;)但是…我尝试将AssociatedObject.Source=bi放入任务的操作委托中,并使用Task.Factory.StartNew(()=>..,CancellationToken.None,TaskCreationOptions.None,taskScheduler);而且它也有效。。。。区别是什么?如果使用TaskScheduler.FromCurrentSynchronizationContext
启动任务,则在当前线程中运行它。您最好根本不使用任务。