我很沮丧地试图解决这个问题。为什么在完成后创建线程并更新UI 如此复杂?!我已经尝试了this,this和this,但我仍然无法清楚地了解整个多线程事物。在Java中这很容易......
无论如何,这是我的代码的简化版作为第三个链接的结果:
private delegate void SimpleDelegate2(BitmapImage bi);
private delegate void SimpleDelegate(string st1, string st2);
private void Process(string st1)
{
try
{
string st2 = "test st2";
SimpleDelegate del = new SimpleDelegate(LongRunningProcess);
del.BeginInvoke(st1, st2, null, null);
}
catch
{
//do some failsafe thing
}
}
private void LongRunningProcess(string st1, string st2)
{
//do some long processing with the strings
BitmapImage bi = new BitmapImage();//there will be an actual bitmap here
SimpleDelegate2 del1 = delegate(BitmapImage bimg)
{
ImageControlOnWPFform.Source = bimg; //null;
};
this.Dispatcher.BeginInvoke(DispatcherPriority.Send, del1, bi);
}
此处的问题是我无法将图片控件的Source
值设置为bimg
,但我可以将其设置为null
!每当我尝试将其设置为bimg
我得到的异常是说调用线程无法访问此对象,因为另一个线程拥有它。我也尝试将其直接设置为bi
,这也会产生相同的异常。
但我可以将源设置为null
而没有任何问题,这意味着我可以修改Image控件的Source
值。但是,如何访问bi
或bimg
?我做错了吗?
另外:我注意到上一个BeginInvoke
的给定参数与方法的任何重载都不匹配,但是它们仍然被认为是有效的并且有效正常。当我指向BeginInvoke
时,我显示的方法重载集完全不同于在方法名称后键入(
时出现的方法重载集。为什么呢?
答案 0 :(得分:2)
在UI线程中使用bi.Freeze()
之前执行BitmapImage
。 Freeze
操作将使BitmapImage
为只读且线程安全。
...
//do some long processing with the strings
BitmapImage bi = new BitmapImage();//there will be an actual bitmap here
bi.Freeze();
SimpleDelegate2 del1 = delegate(BitmapImage bimg)
...
班级System.Windows.Threading.Dispatcher
有五个BeginInvoke
方法签名:
public DispatcherOperation BeginInvoke(Delegate method, params object[] args);
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method);
public DispatcherOperation BeginInvoke(Delegate method, DispatcherPriority priority, params object[] args);
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg);
public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method, object arg, params object[] args);
但是,其中三个签名(DispatcherPriority priority
作为第一个参数的签名)上面有以下标记:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
这就是为什么在方法名称后输入(
时它们不显示的原因。