在后台线程中使用System.AddIn的FrameworkElementAdapters

时间:2014-02-18 19:56:57

标签: c# wpf multithreading add-in

我没有太多了解“为什么”我需要这样做,这是我的情况。我需要创建一个INativeHandleContract来通过AppDomain边界传递UserControl,从新的AppDomain传递到主AppDomain,然后将其添加到StackPanel。但我也试图在另一个线程中这样做。我跑到了一个情况,如果这一切都在同一个线程中运行,那么UserControl似乎正在被正确添加。如果我从一个单独的线程将UserControl添加到StackPanel,它似乎被添加但屏幕上没有任何内容。所以我把它归结为以下代码并找到差异所在。首先是工作代码:

private void AddTestControlInNewThread()
{
    System.Threading.Thread t = new System.Threading.Thread(AddTestControl);
    t.SetApartmentState(System.Threading.ApartmentState.STA);
    t.Start();
}

private void AddTestControl()
{
    INativeHandleContract contract;
    FrameworkElement fe;

    Dispatcher.Invoke(new Action(() => 
    {
        contract = FrameworkElementAdapters.ViewToContractAdapter(new Label() { Content = DateTime.Now.ToString() });
        fe = FrameworkElementAdapters.ContractToViewAdapter(contract);
        parentStackPanel.Children.Add(fe);

    }), null);
}

这很好,但是,在我的场景中,我无法在Dispatcher.Invoke调用中创建“契约”。所以我把它移到了外面,那就是停止工作的地方。以下是代码中的区别:

private void AddTestControl()
{
    INativeHandleContract contract;
    FrameworkElement fe;

    contract = FrameworkElementAdapters.ViewToContractAdapter(new Label() { Content = DateTime.Now.ToString() });

    Dispatcher.Invoke(new Action(() => 
    {

        fe = FrameworkElementAdapters.ContractToViewAdapter(contract);
        parentStackPanel.Children.Add(fe);

    }), null);
}

任何人都可以了解用户控件无法显示的原因,即使它成功添加到parentStackPanel的Children集合中也是如此? 提前谢谢。

1 个答案:

答案 0 :(得分:2)

我很想知道你独特情况背后的原因。我假设Dispatcher与创建parentStackPanel的同一个线程相关联。 WPF控件具有线程关联性,并且必须从同一个线程修改所有控件。您正在构建一个Label对象,在您的第一个示例中,该对象与StackPanel在同一个线程中构建,这是好的。在第二个示例中,它是在不同的线程上构建的,这很可能是代码无法工作的原因。附加一个调试器,你应该抓住某种抛出的异常。