【问题标题】:Running PDFTron in a separate AppDomain: "Cannot pass a GCHandle across AppDomains"在单独的 AppDomain 中运行 PDFTron:“无法跨 AppDomain 传递 GCHandle”
【发布时间】:2017-10-19 09:14:44
【问题描述】:

PDFTron 似乎无法处理多个 AppDomain。从单独的 AppDomain 运行 PDFTron 时,应用程序崩溃并出现未处理的异常(“无法跨 AppDomain 传递 GCHandle”)。

   bei System.Runtime.InteropServices.GCHandle.InternalCheckDomain(IntPtr handle)
   bei System.Runtime.InteropServices.GCHandle.FromIntPtr(IntPtr value)
   bei gcroot<pdftron::PDF::PDFViewWPF ^>.->(gcroot<pdftron::PDF::PDFViewWPF ^>* )
   bei pdftron.PDF.detail.DeluxeCreateTile(Void* data, SByte* buffer, UInt32 width, UInt32 height, UInt32 stride, UInt32 page_num, UInt64 x_page_loc, UInt64 y_page_loc, UInt32 zoomed_page_width, UInt32 zoomed_page_height, UInt32 tile_id, UInt32 x_in_page, UInt32 y_in_page, Int32 canvas_id, Int32 remaining_tiles, Int32 tile_type, Int32 sequenceNum)

在搜索解决方案时,我在 2011 年创建的 Google Groups 论坛中找到了一个主题。用户在他正在开发的 Outlook 插件中遇到了同样的异常。根据主题,PDFTron 支持已经知道该问题,并且在基于 WinForms 的控件之一中也已修复。你可以在这里找到讨论:https://groups.google.com/forum/#!topic/pdfnet-sdk/DGki3Fj2_FU

我是否必须考虑某些事情,或者 PDFTron 根本无法在这种环境中运行?

这是我用来重现问题的示例中的代码:

MainWindow.xaml

<Window x:Class="RunningPdfTronUsingMultipleAppDomains.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RunningPdfTronUsingMultipleAppDomains"
        xmlns:pdf="clr-namespace:pdftron.PDF;assembly=PDFNet"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid x:Name="LayoutRoot">
        <pdf:PDFViewWPF x:Name="PDFView"/>
        <Button Panel.ZIndex="100" Height="20" Width="110" Content="Create AppDomain" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"/>
    </Grid>
</Window>

MainWindow.xaml.cs

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
    {
        PDFDoc document = new PDFDoc("SampleDocument.pdf");
        PDFView.SetDoc(document);
    }

        private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            AppDomain appDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
            var assembly = System.Reflection.Assembly.GetAssembly(typeof(MainWindow));
            appDomain.Load(assembly.GetName());
            Proxy proxy = (Proxy)appDomain.CreateInstanceAndUnwrap(System.Reflection.Assembly.GetExecutingAssembly().GetName().FullName, typeof(Proxy).FullName);
            Thread thread = new Thread(new ParameterizedThreadStart((o) => proxy.Invoke())) { ApartmentState = ApartmentState.STA };
            thread.Start();
        }
    }

Proxy.cs

  public class Proxy : MarshalByRefObject
        {
            public void Invoke()
            {
                try
                {
                    App app = new App();
                    app.Run(new MainWindow());
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }

【问题讨论】:

  • 我不知道 pdftron 的具体情况,但根据错误消息,您只需要确保您不会通过 appdomain 边界传递 GCHandle。您需要这样做吗?
  • 我假设 PDFTron 正在这样做。该异常源自 PDFNet SDK 中的“DeluxeCreateTile”方法。
  • 我假设您创建了单独的 AppDomain。那么你的工作应该是不要跨域移动 pdftron 相关对象。你能提供一个重现问题的stackoverflow.com/help/mcve吗?
  • 我刚刚提供了重现此问题所需的代码。我不知道,是我的代码在域中移动 pdftron 相关对象。那应该是什么对象?
  • 我目前无法运行代码,也许其他人可以。在最简约的场景(没有 ui,没有线程)中也会发生同样的情况吗?

标签: c# appdomain pdftron


【解决方案1】:

仅供参考:PDFTron WPF 6.8(定于 1 月发布)将包括对多个/单独的 AppDomain 的支持

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    相关资源
    最近更新 更多