【问题标题】:"The calling thread must be STA, because many UI components require this." Error in WPF?“调用线程必须是 STA,因为很多 UI 组件都需要这个。” WPF中的错误?
【发布时间】:2010-12-14 12:37:11
【问题描述】:

我正在创建一个 xps 文档,如下所示。

Assembly assembly = Assembly.GetExecutingAssembly();
//read embedded xpsDocument file
Stream helpStream = assembly.GetManifestResourceStream(resourceNameOfContext);
if (helpStream != null)
{
    Package package = Package.Open(helpStream);
    string inMemoryPackageName = "memorystream://" + topicName + ".xps";
    Uri packageUri = new Uri(inMemoryPackageName);
    //Add package to PackageStore
    PackageStore.AddPackage(packageUri, package);
    docXps = new XpsDocument(package, CompressionOption.Maximum, inMemoryPackageName);
}
return docXps;

当我试图获取 docXps.GetFixedDocumentSequence(); 我收到上述错误。有人可以帮忙吗?

谢谢,

【问题讨论】:

  • 您能否将您的代码粘贴四个空格以使其更具可读性?

标签: wpf exception xps


【解决方案1】:

您的问题与创建或使用 XPS 文档的代码无关。它与您正在运行的线程有关。

每当在 MTA 线程上尝试以下任何操作时,您都会收到 The calling thread must be STA, because many UI components require this 错误:

  • 您可以构造任何从 FrameworkElement 派生的对象(包括控件和面板)
  • 您可以构造任何从 BitmapEffect 派生的对象
  • 您可以构造任何从 TextComposition 派生的对象
  • 您可以构造任何从 HwndSource 派生的对象
  • 您访问当前的 InputManager
  • 您访问主 KeyboardDevice、StylusDevice 或 TabletDevice
  • 您尝试将焦点更改为 FrameworkContentElement
  • 您向任何接受文本输入的控件提供鼠标、键盘或 IME 输入
  • 使 WPF 内容可见或更新其布局
  • 您以一种导致重新评估渲染的方式操纵可视化树
  • 其他一些变化,主要与显示和输入有关

例如,去年我在尝试反序列化包含 <Button> 和 WCF 服务中的其他 WPF 对象的某些 XAML 时收到此错误。这个问题很容易解决:我只是切换到一个 STA 线程来进行处理。

显然,大多数使用 XPS 文档的工作都会触发上述一种或多种情况。在您的情况下,我怀疑 GetFixedDocumentSequence 最终使用 TextComposition 或其子类之一。

毫无疑问,我切换到 STA 线程的解决方案也适用于您,但首先您需要弄清楚与 XpsDocuments 一起工作的代码是如何从 MTA 线程运行的。通常来自 GUI 的任何代码(例如按下按钮)都会在 STA 线程中自动运行。

是否有可能在没有 GUI 的情况下执行操作 XPS 文档的代码?来自用户创建的线程?来自 WCF 服务还是 Web 服务?从 ASPX 页面? 跟踪它,您可能会找到解决方案。

如果这不起作用,请告诉我们调用 GetFixedDocumentSequence 的路径的详细信息,以便我们进行诊断。直接围绕的代码并不像调用堆栈和它最初被调用的方式那么重要。如果难以解释,您可能应该添加一个调用堆栈以防止误解并帮助我们进一步诊断问题,或者告诉您如何在您的特定情况下启动 STA 线程。

【讨论】:

    【解决方案2】:

    您的代码是否试图从后台线程访问 xps 文档?如果是这种情况,您将需要使用调度程序。关于here的信息。

    如果这没有帮助,您能否将代码发布到您实际调用 GetFixedDocumentSequence() 的位置?

    【讨论】:

    • 我将此 xps 文档分配给我的自定义类的属性。当我想从自定义类访问这个 xpsdocument 属性时,我正在获取文档,但在 docXps.GetFixedDocumentSequence();
    • 代码如下。私人无效MergeHelpDocument(HelpTopic helpTopic,SerializerWriterCollat​​or vxpsd){尝试{如果(helpTopic.Document!= null){FixedDocumentSequence seqOld = helpTopic.Document.GetFixedDocumentSequence(); // 这里我需要获取文档引用 foreach (DocumentReference r in seqOld.References) { FixedDocument d = r.GetDocument(false);
    • @Ershad:你知道你可以编辑你的问题并添加代码吗?大多数人这样做是因为代码比注释中的代码更容易阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多