var client = new WebClient();
var bytes = client.DownloadData(webUrl); // <-- NOT null
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
BitmapImage img = new BitmapImage();
img.BeginInit();
img.StreamSource = new MemoryStream(bytes); // <-- null
img.EndInit();
img_DownloadCompleted(img, webUrl);
}));
bytes = null; // EDIT: This last line is what I did wrong. This line
// of code is executed in PARALLEL with the anonymous
// function, and thus this variable is set to null
// sometime while (or before) the lambda is executing.
上面的代码在线程中执行,以避免阻塞UI。
我正在尝试从互联网将图像下载到BitmapImage
对象中。图像已正确下载,但是当我尝试在UI中使用(使用Dispatcher.Invoke
)时,出现以下错误消息:The calling thread cannot access this object because a different thread owns it.
因此,我添加了在UI线程上创建图像的代码。但是现在,当代码到达时<-- null
,变量指示的行bytes
突然变为空。在执行进入匿名函数之前,它不为null。(我检查了调试器)
有人知道为什么吗?Google并不是很有帮助。
更改变量类型的bytes
,以var
不作任何区别。
很可能您以后要更改bytes
变量,从而在匿名函数中修改“捕获的”值。就像是:
var bytes = client.DownloadData(webUrl); <-- NOT null
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
... img.StreamSource = new MemoryStream(bytes); <-- null
...
}
bytes = null; // something like this - because why not?
请注意,即使代码如下顺序和img.StreamSource = ...
是前 bytes = null;
行,它实际上很可能会以相反的顺序(因为它运行在其他线程不确定性)执行。
您应该非常小心将在以后/在其他线程上异步执行的捕获。比较安全的选择是在单独的方法中创建匿名函数,这样您以后就无法更改捕获的变量了:
Action CreateBitmapAction(bytes[] bytes)
{
return () =>
{
BitmapImage img = new BitmapImage();
img.BeginInit();
img.StreamSource = new MemoryStream(bytes);
img.EndInit();
img_DownloadCompleted(img, webUrl);
};
}
Application.Current.Dispatcher.BeginInvoke(CreateBitmapAction(bytes));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句