我正在使用2015和.Net
我遇到了一个有点奇怪的问题。我有一个包含两个项目的C#解决方案。一个是标准的WPF应用程序,另一个是WPF用户控制库。WPF应用程序项目是启动项目。在每个项目中,我都有一个窗口。在启动项目中,我打开窗口并使用CallContext.LogicalSetData在逻辑调用上下文中设置一个值。这是在装载时完成的。然后在WPF用户控制库中关闭该窗口并打开该窗口。我用逻辑调用上下文中的值填充一个文本框(使用CallContext.LogicalGetData),这样做很好。我有一个按钮,该按钮在单击时触发一个事件,该事件使用来自逻辑调用上下文的相同值填充另一个文本框--但突然间该值为空。
我可以简单地通过更改启动窗口来使其工作,而不是在加载时做“事情”,而是在按钮事件上。
启动窗口代码:
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解决方案作为zip文件
注意-我不是在寻找解决办法(我有几个),我在寻找发生这种情况的原因。
发布于 2016-10-14 16:50:27
这是因为包含Thread.CurrentThread.ExecutionContext的DataStore的CallContext实例在调用之间发生了变化。如果在Visual调试器中使用“”,您可以检查是否给它一个标记。
这一切为什么要发生?我完全不知道。我试图调试.net框架源代码,但没有取得任何成功。
就AsyncLocal<T>而言:它也使用相同的Thread.CurrentThread.ExecutionContext,因此也存在相同的问题。
如果使用ThreadLocal<T>,则不会发生这种情况,因为这是在使用[ThreadStatic],而Thread本身并没有改变。
https://stackoverflow.com/questions/40045468
复制相似问题