嗯,我在一个asp.net 3.5网站上工作。
我像这样设置了一个观察者:
public delegate void ActionNotification();
protected Dictionary<string, List<ActionNotification>> Observers
{
get
{
Dictionary<string, List<ActionNotification>> _observers = Session["Observers"] as Dictionary<string, List<ActionNotification>>;
if (_observers == null)
{
_observers = new Dictionary<string, List<ActionNotification>>();
Observers = _observers;
}
return _observers;
}
set
{
Session["Observers"] = value;
}
}
public void Attach(string actionName, ActionNotification observer)
{
if (!Observers.ContainsKey(actionName))
{
Observers.Add(actionName, new List<ActionNotification>());
}
Observers[actionName].Add(observer);
}
public void Detach(string actionName, ActionNotification observer)
{
if (Observers.ContainsKey(actionName))
{
Observers[actionName].Remove(observer);
}
}
public void DetachAll(string actionName)
{
if (Observers.ContainsKey(actionName))
{
Observers.Remove(actionName);
}
}
public void Notify(string action)
{
if (Observers.ContainsKey(action))
{
foreach (ActionNotification o in Observers[action])
{
o.Invoke();
}
}
}我像这样使用观察者:
//Esta es llamada al notify con cierto action
protected void btnNext_Click(object sender, ImageClickEventArgs e)
{
Notify("Next");
}
//Y este es el register del Listener
Attach("Next", new ActionNotification(NextButton_Click)); 如果在o.Invoke()之前;例如,我将页面标题更改为"Hello“。在"NextButton_Click“中,我将其设置为”再见“,在NextButton_Click结束后,标题又回到”Hello“……
知道为什么吗?
发布于 2011-08-19 08:02:07
我认为问题在于NextButton_Click事件中的“页面”与您将标题设置为"Hello“的页面不是同一个页面。因为在引发事件时,您正在传递会话中的事件,所以acts所在的对象不再在作用域中。您可以使用以下代码(使用EventHandlers,但它们基本上与您在代码中概述的内容相同)重新创建它。
protected void Page_Load(object sender, EventArgs e)
{
this.Page.Title = "test";
//Store it in your session...seems like a weird thing to do given how your page should be stateless, so I would think about what you are
//trying to do a bit more carefully. You don't want to call an event handler such as test below from another page in your asp.net app.
Dictionary<string, EventHandler> myEvents = null;
if (Session["Invokers"] == null)
{
myEvents = new Dictionary<string, EventHandler>();
Session["Invokers"] = myEvents;
}
else
{
myEvents = Session["Invokers"] as Dictionary<string, EventHandler>;
}
//If the event handler key is not in there then add it
if (myEvents.ContainsKey("buttonClickOnPageDefault") == false)
{
//Subscribe to event (i.e. add your method to the invokation list
this.TestEvent += new EventHandler(test);
myEvents.Add("buttonClickOnPageDefault", this.TestEvent);
}
else
{
//if it does contain this key then you may already be subscribed to event, so unsubscribe in case and then resubscribe...you could
//probably do this more elegantly by looking at the vales in the GetInvokationList method on the eventHandler
//Wire up the event
this.TestEvent -= new EventHandler(test);
this.TestEvent += new EventHandler(test);
}
//Resave the dictionary.
Session["Invokers"] = myEvents;
}
void test(object o, EventArgs e)
{
this.Page.Title = "testEvent";
}
public event EventHandler TestEvent;
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["Invokers"] != null)
{
Dictionary<string, EventHandler> myEvents = (Dictionary<string, EventHandler>)Session["Invokers"];
if (myEvents.ContainsKey("buttonClickOnPageDefault"))
{
EventHandler ev = myEvents["buttonClickOnPageDefault"];
ev(null, EventArgs.Empty);
}
}
}如果您将上述代码放在asp.net页面中,它将永远不会更改页面标题,但是如果您在Test方法中放置断点,您将看到它被击中。原因是它在不同的页面中被命中(该页面超出范围,可能不会被垃圾回收,因为您的事件仍然有对它的引用,所以这可能会导致内存leak...be小心处理它!)。实际上,您可能不应该以这种方式使用事件(至少不应作用于page...maybe,它有一些域对象实用程序)。请注意,以下代码将起作用(因为它在同一页面上运行)
protected void Page_Load(object sender, EventArgs e)
{
this.Page.Title = "test";
//Store it in your session...seems like a weird thing to do given how your page should be stateless, so I would think about what you are
//trying to do a bit more carefully. You don't want to call an event handler such as test below from another page in your asp.net app.
this.TestEvent += new EventHandler(test);
Session["Invoker"] = this.TestEvent;
}
void test(object o, EventArgs e)
{
this.Page.Title = "testEvent";
}
public event EventHandler TestEvent;
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["Invoker"] != null)
{
EventHandler ev = (EventHandler)Session["Invoker"];
ev(null, EventArgs.Empty);
}
}希望这能给你一些提示,指出你的问题所在。
https://stackoverflow.com/questions/7114968
复制相似问题