【问题标题】:InvalidOperationException delegation UI Thread C#InvalidOperationException 委托 UI 线程 C#
【发布时间】:2015-10-24 12:33:41
【问题描述】:

我收到InvalidOperationException。此代码在线程中运行。我已将其委托给 UI 线程来处理 UI。是不是因为我的资源问题?

BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/LiarDice;component/" + imagePath);
logo.EndInit();
currentGuessDice.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate()
{
    currentGuessDice.Source = logo;
}));

我稍微更改了我的代码,现在错误变为:

Part URI cannot end with a forward slash.

新代码:

currentGuessDice.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                new Action(delegate()
                {
                    BitmapImage logo = new BitmapImage();
                    logo.BeginInit();
                    logo.UriSource = new Uri("pack://application:,,,/LiarDice;component/" + imagePath);
                    logo.EndInit();
                    currentGuessDice.Source = logo;
                }));

【问题讨论】:

  • 是什么让您认为它与多线程或线程(UI)有关?异常清楚地表明这是 URI 解析错误。
  • 在我编辑代码并将整个初始化放在 Dispatcher 中之前,它出现了 InvalidOperationException。

标签: c# wpf multithreading xaml


【解决方案1】:

除了你的imagePath变量我是null之外,你原始代码中的问题是你在UI线程之外的线程中创建了一个BitmapImage,然后在UI线程中使用它。

BitmapImage 是一个DispatcherObject,这意味着它有thread affinity。由于它也是Freezable,因此您可以冻结它以使其可供创建它的线程以外的线程访问:

var logo = new BitmapImage(
    new Uri("pack://application:,,,/LiarDice;component/" + imagePath));

logo.Freeze(); // here

currentGuessDice.Dispatcher.Invoke(new Action(() => currentGuessDice.Source = logo));

【讨论】:

  • Oic。我就是这么想的。我已经将代码放在 ui 线程中。什么会更好?在 UI 线程中初始化 BitmapImage 或使用 .Freeze() ?
  • 创建和冻结 BitmapImage 会更好,因为它会保留 UI 线程的工作。这就是为什么你首先有一个后台线程。但是,如果它不是一个非常大的位图,您几乎不会注意到任何差异。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
相关资源
最近更新 更多