Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 超时时从异步控制器中删除事件侦听器_Asp.net Mvc 3_Asynccontroller - Fatal编程技术网

Asp.net mvc 3 超时时从异步控制器中删除事件侦听器

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

我对MVC3 asynccontroller有一个问题,当controller asyc方法运行时,我递增asynccontroller,并开始侦听backednd事件

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
    }
}