我在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
说:< / p>
已添加具有相同键的项目
我觉得我错过了关于应用程序生命周期的基本信息,但是到目前为止还没有发现任何有用的信息。在添加它之前,我可以将.Add()
包装在条件中以检查密钥,但我觉得这是一个绑定。我错过了什么?
提前致谢!
答案 0 :(得分:1)
<强> ehhmm ... 强>
如果您不使用静态字典作为一种共享内存缓存,则可以删除示例代码的所有静态关键字。在这种情况下,您也无需调用Clear()
方法。
如果您使用static
词典作为一种内存缓存(我不建议使用),您可能会遇到多次调用您的页面会导致竞争状况,因为它们可能会被不同的处理线程。为了解决这个问题,你可以使用一个lock语句来强制线程同步对字典的非线程安全调用,如下所示:
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());
}
}
请注意;这是一个肮脏的修复程序,它将有效地取消对此特定调用的所有多线程优化web服务器(从而导致性能损失)。