【问题标题】:Null reference when printing WPF FixedPage in Windows 8.1在 Windows 8.1 中打印 WPF FixedPage 时的空引用
【发布时间】:2019-03-22 15:22:48
【问题描述】:

我有一个 .net framework v4.7.2 WPF 应用程序,它打印了一个 FixedPage,它在 Windows 7 上运行没有任何问题,但在 Windows 8.1 上运行它时遇到了一些问题。

以下代码块是导致问题的原因:

private void Print()
{
    using (var printQueue = LocalPrintServer.GetDefaultPrintQueue())
    {
        var printTicket = printQueue.DefaultPrintTicket;
        var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
        writer.WritingCompleted += OnDocumentWritten;
        writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
    }
}

它会抛出一个 NullReferenceException 并带有以下堆栈跟踪:

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Collections.Hashtable.get_Item(Object key)
   at System.Printing.PrintQueue.get_IsXpsDevice()
   at System.Printing.PrintQueue.ForwardXpsDriverDocEvent(Object sender, XpsSerializationXpsDriverDocEventArgs args)
   at System.Windows.Xps.Serialization.XpsSerializationManager.OnXpsDriverDocEvent(XpsSerializationXpsDriverDocEventArgs e)
   at System.Windows.Xps.Serialization.XpsDriverDocEventManager.OnXpsDriverDocEvent()
   at System.Windows.Xps.Serialization.XpsDriverDocEventManager.ForwardPackagingProgressEvent(Object sender, PackagingProgressEventArgs e)
   at System.Windows.Xps.Packaging.PackagingProgressEventHandler.Invoke(Object sender, PackagingProgressEventArgs e)
   at System.Windows.Xps.Packaging.XpsInterleavingPolicy.AddItem(INode n, Int32 number, INode parent)
   at System.Windows.Xps.Serialization.XpsPackagingPolicy.AcquireXmlWriterForFixedPage()
   at System.Windows.Xps.Serialization.XpsSerializationManager.AcquireXmlWriter(Type writerType)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.get_XmlWriter()
   at System.Windows.Xps.Serialization.ReachTreeWalker..ctor(ReachSerializer serializer)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.PersistObjectData(SerializableObjectContext serializableObjectContext)
   at System.Windows.Xps.Serialization.ReachSerializerAsync.BeginSerializeObject(Object serializedObject)
   at System.Windows.Xps.Serialization.FixedPageSerializerAsync.SerializeObject(Object serializedObject)
   at System.Windows.Xps.Serialization.XpsSerializationManagerAsync.InvokeSaveAsXamlWorkItem(Object arg)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

如果我用writer.Write(...) 替换writer.WriteAsync(...),错误就会消失。

我已经能够在 Windows 8.1、Windows Server 2012 R2 和 Windows Server 2016 上重现该错误。我无法在 Windows 10 上重现该错误。

关于如何在 Windows 8.1 上进行异步打印有什么建议吗?

【问题讨论】:

  • 您可能需要在 printQueue 中保持对该实例的引用,或者至少在打印完成之前不要对其调用 Dispose。看起来您可以将 Disposing 推迟到 OnDocumentWritten 方法。
  • @rene OP 在 using 块内使用异步方法而不等待它

标签: c# wpf windows


【解决方案1】:

您可以将方法 async 然后 await 异步调用。

试试这个:

private async Task Print()
{
    using (var printQueue = LocalPrintServer.GetDefaultPrintQueue())
    {
        var printTicket = printQueue.DefaultPrintTicket;
        var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
        writer.WritingCompleted += OnDocumentWritten;
        await writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
    }
}

【讨论】:

    【解决方案2】:

    @rene 的回答解决了这个问题,所以显然问题是 PrintQueue 在打印完成之前就被处置了。

    private void Print()
    {
        var printQueue = LocalPrintServer.GetDefaultPrintQueue()
        var printTicket = printQueue.DefaultPrintTicket;
        var writer = PrintQueue.CreateXpsDocumentWriter(printQueue);
        writer.WritingCompleted += OnDocumentWritten;
        writer.WriteAsync(View.LabelPageView.AddressLabelPage, printTicket);
    }
    

    然而,代码在 Windows 10 上运行但在 Windows 8.1 上运行似乎很奇怪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2015-11-23
      • 1970-01-01
      • 2012-11-02
      相关资源
      最近更新 更多