方法在 Page_Load 中被乱序调用了两次
Method called twice out of order in Page_Load
我在 SharePoint Stack Exchange 中询问过这个问题,但认为它可能不是特定于 SharePoint 的问题,可能与 .NET 页面生命周期有更多关系。原题可见here.
我正在为 SharePoint 2013 编写 Web 应用程序,并且正在 运行 关注一些有趣的行为。基本上,我正在发出一系列网络请求,但首先需要将这些请求存储在 Dictionary
中以备后用。但是,如果我在调试时打开 3 个选项卡并同时点击它们,我会看到 Dictionary
对象未清空并在它尝试多次添加相同端点时导致异常。下面是应用的相关代码:
public partial class TestControl : UserControl
{
protected static Dictionary<string, string> _endpoints = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
//clear the lists of endpoints each time the page is loaded
_endpoints.Clear();
...
MethodThatAddsToDictionary();
...
}
public static void MethodThatAddsToDictionary()
{
...
_endpoints.Add(response.First(), response.Last());
}
}
调试,有时 MethodThatAddsToDictionary()
在 _endpoints.Clear()
之前被调用两次 运行 在 Page_Load
事件的顶部,我会得到一个 ArgumentException
说:
an item with the same key has already been added
我觉得我缺少关于应用程序生命周期的一些基本知识,但到目前为止还没有找到任何有用的东西。我可以将 .Add()
包装在有条件的条件中以在添加之前检查密钥,但我觉得那是创可贴。我错过了什么?
提前致谢!
嗯哼……
如果您不使用静态字典作为一种共享内存缓存,您可以删除示例代码中的所有静态关键字。在那种情况下,您也不需要调用 Clear()
方法。
如果您将 static
词典用作一种内存缓存(我不推荐这样做),您可能会遇到对页面的多次调用会导致竞争条件,因为它们可能会被处理通过不同的线程。为了解决这个问题,作为创可贴,您可以使用锁定语句在对字典的非线程安全调用上强制线程同步,如下所示:
public partial class TestControl : UserControl
{
protected static Dictionary<string, string> _endpoints =
new Dictionary<string, string>();
//lock object needs to be static in this case
private static object _lockObject = new object();
protected void Page_Load(object sender, EventArgs e)
{
lock(_lockObject) //only one thread may pass at the same time,
//others will wait.
{
//clear the lists of endpoints each time the page is loaded
_endpoints.Clear();
...
MethodThatAddsToDictionary();
}
}
public static void MethodThatAddsToDictionary()
{
...
_endpoints.Add(response.First(), response.Last());
}
}
请注意;这是一个肮脏的修复,将有效地取消针对此特定调用的网络服务器的所有多线程优化(因此会导致性能下降)。
我在 SharePoint Stack Exchange 中询问过这个问题,但认为它可能不是特定于 SharePoint 的问题,可能与 .NET 页面生命周期有更多关系。原题可见here.
我正在为 SharePoint 2013 编写 Web 应用程序,并且正在 运行 关注一些有趣的行为。基本上,我正在发出一系列网络请求,但首先需要将这些请求存储在 Dictionary
中以备后用。但是,如果我在调试时打开 3 个选项卡并同时点击它们,我会看到 Dictionary
对象未清空并在它尝试多次添加相同端点时导致异常。下面是应用的相关代码:
public partial class TestControl : UserControl
{
protected static Dictionary<string, string> _endpoints = new Dictionary<string, string>();
protected void Page_Load(object sender, EventArgs e)
{
//clear the lists of endpoints each time the page is loaded
_endpoints.Clear();
...
MethodThatAddsToDictionary();
...
}
public static void MethodThatAddsToDictionary()
{
...
_endpoints.Add(response.First(), response.Last());
}
}
调试,有时 MethodThatAddsToDictionary()
在 _endpoints.Clear()
之前被调用两次 运行 在 Page_Load
事件的顶部,我会得到一个 ArgumentException
说:
an item with the same key has already been added
我觉得我缺少关于应用程序生命周期的一些基本知识,但到目前为止还没有找到任何有用的东西。我可以将 .Add()
包装在有条件的条件中以在添加之前检查密钥,但我觉得那是创可贴。我错过了什么?
提前致谢!
嗯哼……
如果您不使用静态字典作为一种共享内存缓存,您可以删除示例代码中的所有静态关键字。在那种情况下,您也不需要调用 Clear()
方法。
如果您将 static
词典用作一种内存缓存(我不推荐这样做),您可能会遇到对页面的多次调用会导致竞争条件,因为它们可能会被处理通过不同的线程。为了解决这个问题,作为创可贴,您可以使用锁定语句在对字典的非线程安全调用上强制线程同步,如下所示:
public partial class TestControl : UserControl
{
protected static Dictionary<string, string> _endpoints =
new Dictionary<string, string>();
//lock object needs to be static in this case
private static object _lockObject = new object();
protected void Page_Load(object sender, EventArgs e)
{
lock(_lockObject) //only one thread may pass at the same time,
//others will wait.
{
//clear the lists of endpoints each time the page is loaded
_endpoints.Clear();
...
MethodThatAddsToDictionary();
}
}
public static void MethodThatAddsToDictionary()
{
...
_endpoints.Add(response.First(), response.Last());
}
}
请注意;这是一个肮脏的修复,将有效地取消针对此特定调用的网络服务器的所有多线程优化(因此会导致性能下降)。