CallContext - 值消失 - WPF

时间:2016-10-14 14:19:13

标签: c# wpf

我正在使用Visual Studio 2015和.Net

我遇到了一个有点奇怪的问题。我有一个包含两个项目的C#解决方案。一个是标准WPF应用程序,另一个是WPF用户控件库。 WPF应用程序项目是启动项目。 在每个项目中,我都有一个窗口。在启动项目中,我打开窗口并使用CallContext.LogicalSetData在逻辑调用上下文中设置一个值。这是在加载时完成的。然后我关闭窗口并打开WPF用户控件库中的窗口。我使用逻辑调用上下文中的值填充一个文本框(使用CallContext.LogicalGetData),这很好。 我有一个按钮,在单击时触发一个事件,该事件使用逻辑调用上下文中的相同值填充另一个文本框 - 但突然之间该值为null。

我可以简单地通过更改启动窗口来使其工作,而不是在加载时执行“事物”,而是按钮事件。

启动窗口代码:

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

    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        CallContext.LogicalSetData("test", "value set onload");
        TestWindow win = new TestWindow();
        win.Show();
        this.Close();
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        CallContext.LogicalSetData("test", "value set on button event");
        TestWindow win = new TestWindow();
        win.Show();
        this.Close();
    }
}

如上所述,如果我在OnLoaded方法中注释掉这四行,那么它可以正常工作。

另一个窗口:

    public partial class TestWindow : Window
{
    public TestWindow()
    {
        InitializeComponent();
        PreLoadedText.Text = CallContext.LogicalGetData("test") as string;
    }

    private void GetValue_Click(object sender, RoutedEventArgs e)
    {
        string eventTextText = CallContext.LogicalGetData("test") as string;
        EventText.Text = eventTextText ?? "The value is null";
    }
}

顺便说一下。我尝试使用AsyncLocal<T>类 - 但我遇到了同样的问题。

示例解决方案可以在这里找到: Visual studio solution as zip file

注意 - 我没有寻找解决方法(我有一对),我正在寻找发生这种情况的原因。

1 个答案:

答案 0 :(得分:3)

这是因为Thread.CurrentThread.ExecutionContext的实例(包含DataStore的{​​{1}})在调用之间发生了变化。如果通过在Visual Studio调试器中使用“生成对象ID”为其指定标记,则可以检查它。

为什么会这样?我完全不知道。我试图调试.net Framework源代码而没有任何运气。

CallContext而言:它也使用相同的AsyncLocal<T>,因此会遇到同样的问题。

如果您使用Thread.CurrentThread.ExecutionContext,则不会发生这种情况,因为它使用的是ThreadLocal<T>[ThreadStatic]本身并未发生变化。