WeakReference <t>在目标是实时</t>时返回null

时间:2014-01-16 12:24:26

标签: c# .net windows-phone-8

我编写了一个消息调度程序,其中对每个订阅者的引用存储为Reference

订阅者的一部分:

public Service(IMessageHub messageHub)
{
    Guard.NotNull(messageHub);

    messageHub.Subscribe<UserLogoutMessage>(UserLogOut);
}

~Service()
{
    // I have add it to check is it finalized or isn't it
    new object();
}

private void UserLogOut(UserLogoutMessage obj)
{
    GoToLoginPage();
}

MessageHub的订阅代码:

var weakRefference = new WeakReference<Action<TMessage>>(handler, true);
handlers.Add(weakRefference);

return new DisposeAction(() => Unsubscribe(weakRefference));

MessageHub的发送消息代码:

foreach (var weakRefference in handlers.ToArray())
{
    Action<TMessage> handler;

    // The TryGetTarget method return false here
    if (weakRefference.TryGetTarget(out handler))
    {
        try
        {
            handler(message);
        }
        catch
        { }
    }
    else
    {
        cleanRequired = true;
    }
}

每当我尝试发送消息时,弱引用返回null并且我的代码不正确。 我已检查服务仍然可用,但尚未最终确定。 你能帮我找到问题的根本原因吗?

P.S。我正在通过PCL开发Windows Phone 8

1 个答案:

答案 0 :(得分:2)

我知道这是一个老问题,但是如果有人从搜索引擎到达这里,问题是因为你存储了对Action<TMessage>的弱引用,这是一个临时对象,因此很可能已被收集。

解决方案有点复杂;你基本上必须单独存储代理的各个部分,就像你用一个强引用存储代表一样,你将使目标保持活着,正如你所见,如果你用一个弱引用存储委托它可以在目标还活着时进行垃圾收集。

我认为您可以做的是将委托的Target属性存储在弱引用中,并将GetMethodInfo的结果存储在单独的字段中 - 当需要调用您刚刚调用的处理程序时Invoke的{​​{1}}方法与弱引用的对象,如果它仍然存在。

如果您需要更多信息,请与我们联系。