Asp.net mvc 3 超时时从异步控制器中删除事件侦听器
我对MVC3 asynccontroller有一个问题,当controller asyc方法运行时,我递增asynccontroller,并开始侦听backednd事件Asp.net mvc 3 超时时从异步控制器中删除事件侦听器,asp.net-mvc-3,asynccontroller,Asp.net Mvc 3,Asynccontroller,我对MVC3 asynccontroller有一个问题,当controller asyc方法运行时,我递增asynccontroller,并开始侦听backednd事件 AsyncManager.OutstandingOperations.Increment(); eventAggregator.Subscribe(this); 然后当后端事件触发时,我减少并取消订阅后端事件 AsyncManager.OutstandingOperations.Decrement(); eventAggre
AsyncManager.OutstandingOperations.Increment();
eventAggregator.Subscribe(this);
然后当后端事件触发时,我减少并取消订阅后端事件
AsyncManager.OutstandingOperations.Decrement();
eventAggregator.Unsubscribe(this);
这是可行的,但如果控制器超时,eventAggregator将保留对控制器的订阅(这是一个弱防护列表,但由于某些原因,旧控制器未被删除)当后端事件触发时,旧控制器将首先窃取事件并将事件出列,这意味着当真正的控制器收到消息时,队列为空,没有任何内容发送到视图,这也是内存泄漏,因此几分钟后Weakreference列表中会有很多控制器。。。当控制器超时时,如何从eventaggregator取消订阅
编辑:事件聚合器的代码,我们对此代码进行了单元测试,证明没有内存泄漏。奇怪的是,如果我创建一个没有任何引用的空标准控制器,它的解构器也不会运行。。。我们使用国际奥委会(Ninject)这会是问题吗
public class EventAggregator : IEventAggregator
{
private readonly IConfig config;
private readonly WeakReferenceList<object> subscribers = new WeakReferenceList<object>();
public EventAggregator(IConfig config)
{
this.config = config;
}
public void Subscribe(object subsriber)
{
subscribers.Add(subsriber);
}
public void Unsubscribe(object subscriber)
{
subscribers.Remove(subscriber);
}
public void Publish<T>(T message) where T : class
{
var lookupType = typeof (IHandle<T>);
if (config.EnableEventAggregator)
subscribers.Where(lookupType.IsInstanceOfType)
.Select(s => s as IHandle<T>)
.ForEach(s => s.Handle(message));
}
}
public class WeakReferenceList<T> : ICollection<T> where T : class
{
private readonly List<WeakReference> list = new List<WeakReference>();
public IEnumerator<T> GetEnumerator()
{
return GetAlive().Select(item => item.Target as T).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
CleanDeadReferences();
list.Add(new WeakReference(item));
}
public void Clear()
{
list.Clear();
}
public bool Contains(T item)
{
return GetAlive().Any(weakItem => weakItem.Target.Equals(item));
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(T item)
{
CleanDeadReferences();
return list.RemoveAll(weakItem => weakItem.Target.Equals(item)) > 0;
}
public int Count
{
get { return GetAlive().Count(); }
}
public bool IsReadOnly
{
get { return false; }
}
public int IndexOf(T item)
{
var weakItem = list.First(x => x.Target == item);
return list.IndexOf(weakItem);
}
public void Insert(int index, T item)
{
CleanDeadReferences();
list.Insert(index, new WeakReference(item));
}
private IEnumerable<WeakReference> GetAlive()
{
return list.ToList().Where(item => item.IsAlive);
}
private void CleanDeadReferences()
{
list.RemoveAll(item => !item.IsAlive);
}
}
公共类事件聚合器:IEventAggregator
{
私有只读IConfig配置;
私有只读WeakReferenceList订阅服务器=新建WeakReferenceList();
公共事件聚合器(IConfig配置)
{
this.config=config;
}
公共无效订阅(对象订阅器)
{
添加(subscriber);
}
公共无效取消订阅(对象订阅方)
{
订阅服务器。删除(订阅服务器);
}
公共无效发布(T消息),其中T:class
{
var lookupType=typeof(IHandle);
if(config.EnableEventAggregator)
订阅服务器。其中(lookupType.IsInstanceOfType)
.选择(s=>s作为IHandle)
.ForEach(s=>s.Handle(message));
}
}
公共类WeakReferenceList:i集合,其中T:class
{
私有只读列表=新列表();
公共IEnumerator GetEnumerator()
{
返回GetAlive();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
公共作废新增(T项)
{
CleanDeadReferences();
列表。添加(新的WeakReference(项目));
}
公共空间清除()
{
list.Clear();
}
公共布尔包含(T项)
{
返回GetAlive().Any(weakItem=>weakItem.Target.Equals(item));
}
public void CopyTo(T[]数组,int arrayIndex)
{
抛出新的NotImplementedException();
}
公共布尔删除(T项)
{
CleanDeadReferences();
return list.RemoveAll(weakItem=>weakItem.Target.Equals(item))>0;
}
公共整数计数
{
获取{return GetAlive().Count();}
}
公共图书馆是只读的
{
获取{return false;}
}
公共整数索引(T项)
{
var weakItem=list.First(x=>x.Target==item);
返回列表。IndexOf(weakItem);
}
公共空白插入(整数索引,T项)
{
CleanDeadReferences();
列表.插入(索引,新的WeakReference(项目));
}
私有IEnumerable GetAlive()
{
return list.ToList().Where(item=>item.IsAlive);
}
私有void CleanDeadReferences()
{
list.RemoveAll(item=>!item.IsAlive);
}
}
您可以覆盖该方法:
要定义超时时间,您可以使用该属性。谢谢,这可能解决了问题,但没有解决症状,出于某种原因,MVC3没有释放对控制器的引用,不是很奇怪吗?@Anders,我想您意识到,如果不显示代码,我几乎帮不上什么忙。看看你的问题:你已经展示了2行代码,并提供了0个关于这个
eventAggregator
变量是什么,如何实现的信息。。。理想情况下,将您的问题缩小到一个样本,您可以在这里发布,这将允许我们复制您的问题。否则,我恐怕这将是接近不可能帮助你。对不起,请参阅编辑。您的解决方案有效,因此原来的问题实际上得到了回答
protected override void EndExecute(IAsyncResult asyncResult)
{
try
{
base.EndExecute(asyncResult);
}
catch(TimeoutException ex)
{
// Clean up your references here
}
}