Page_Load中两次无序调用的方法 [英] Method called twice out of order in Page_Load
问题描述
我在SharePoint Stack Exchange中进行了询问,但认为这可能不是SharePoint特定的问题,并且可能与.NET页面生命周期有很大关系.原始问题可以在此处找到.
I asked this over in the SharePoint Stack Exchange but figured it might not be a SharePoint-specific question and might have more to do with the .NET page lifecycle. The original question can be found here.
我正在为SharePoint 2013编写一个Web应用程序,并且遇到了一些有趣的行为.基本上,我要进行一系列Web请求,但首先需要将它们存储在 Dictionary
中,以备后用.但是,如果在调试时打开3个选项卡并同时单击它们,我会发现 Dictionary
对象没有被清空,并且在尝试多次添加同一终结点时会导致异常.这是应用程序的相关代码:
I am writing a web app for SharePoint 2013 and am running into some interesting behavior. Basically, I am making a series of web requests, but first need to store those in a Dictionary
for use later. However, if I open 3 tabs while debugging and hit them at the same time, I see the Dictionary
object is not emptied and causes an exception when it tries to add the same endpoint multiple times. Here is the relevant code of the app:
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
:
Debugging, sometimes MethodThatAddsToDictionary()
is called twice before the _endpoints.Clear()
is run at the top under the Page_Load
event and I'll get an ArgumentException
saying:
具有相同键的项目已添加
an item with the same key has already been added
我觉得我缺少有关该应用程序生命周期的一些基本知识,但到目前为止还没有发现任何可行的方法.我可以在有条件的条件下包装 .Add()
来检查密钥,然后再添加它,但是我觉得这是一个创可贴.我想念什么?
I feel like I'm missing something basic about the lifecycle of the app but haven't found anything that works so far. I could wrap the .Add()
in a conditional to check for the key before I add it, but I feel like that is a bandaid. What am I missing?
提前谢谢!
推荐答案
ehhmm ... 如果您不将静态字典用作一种共享内存缓存,则可以将示例示例中的所有静态关键字都删除.在这种情况下,您也不需要调用 Clear()
方法.
如果您将 static
词典用作一种内存缓存(我不建议这样做),则您可能会遇到对页面的多次调用会导致竞争的情况,因为它们可能是由不同的线程处理.为了解决这个问题,您可以作为一个创可贴,使用lock语句在对字典的非线程安全调用上强制执行线程同步,如下所示:
If you use your static
dictionary as a sort of memory cache, which I wouldn't recommend, you might experience that multiple calls to your page will result in a race condition, since they might be handled by different threads. In order to fix this, you can, as a band-aid, use a lock statement to force thread synchronization on the non-thread-safe call to the dictionary like this:
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());
}
}
请注意;这是一个肮脏的修补程序,将针对该特定调用有效地取消webs-server的所有多线程优化(从而导致性能下降).
Please note; this is a dirty fix and will effectively cancels all multithreading optimizations of the webs-server for this specific call (and thus causes a performance penalty).
这篇关于Page_Load中两次无序调用的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!