CallContext – 值消失 - WPF

Yko*_*kok 5 c# wpf

我正在使用 Visual Studio 2015 和 .Net

\n\n

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

\n\n

我可以简单地通过更改启动窗口来使其工作,使其在加载时不执行 \xe2\x80\x99s \xe2\x80\x9cthing\xe2\x80\x9d 操作,而是在按钮事件上执行。

\n\n

启动窗口代码:

\n\n
public partial class MainWindow : Window\n{\n    public MainWindow()\n    {\n        this.Loaded += OnLoaded;\n        InitializeComponent();\n    }\n\n    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)\n    {\n        CallContext.LogicalSetData("test", "value set onload");\n        TestWindow win = new TestWindow();\n        win.Show();\n        this.Close();\n    }\n\n    private void button_Click(object sender, RoutedEventArgs e)\n    {\n        CallContext.LogicalSetData("test", "value set on button event");\n        TestWindow win = new TestWindow();\n        win.Show();\n        this.Close();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

另一个窗口:

\n\n
    public partial class TestWindow : Window\n{\n    public TestWindow()\n    {\n        InitializeComponent();\n        PreLoadedText.Text = CallContext.LogicalGetData("test") as string;\n    }\n\n    private void GetValue_Click(object sender, RoutedEventArgs e)\n    {\n        string eventTextText = CallContext.LogicalGetData("test") as string;\n        EventText.Text = eventTextText ?? "The value is null";\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

示例解决方案可以在此处找到:\n Visual Studio 解决方案作为 zip 文件

\n\n

注意 - 我不是在寻找解决方法(我有几个),我正在寻找发生这种情况的原因。

\n

hai*_*ndl 3

这是因为 的实例Thread.CurrentThread.ExecutionContext(包含DataStore的 )CallContext在调用之间发生了变化。您可以通过在 Visual Studio 调试器中使用“生成对象 ID”来检查是否为其指定了标记。

为什么会出现这种情况?我完全不知道。我尝试调试 .net Framework 源代码,但没有成功。

就目前而言AsyncLocal<T>:它也使用相同的方法Thread.CurrentThread.ExecutionContext,因此遇到同样的问题。

如果你使用它就不会发生,ThreadLocal<T>因为它正在使用[ThreadStatic]并且它Thread本身不会改变。