【问题标题】:Do I need to unsubscribe?我需要退订吗?
【发布时间】:2018-10-01 10:15:26
【问题描述】:

我有以下代码:

public void UnPublishDatabases(IReadOnlyCollection<IPublishedDatabase> sqlDatabases)
{
    var listener = new UnpublishDatabaseListener();
    listener.DatabaseUnpublished += db =>
    {
        OnDatabaseUnpublished(db); 
        listener.DatabaseUnpublished -= OnDatabaseUnpublished;
    };

    _publishController.Unpublish(sqlDatabases, listener);
    //...
}

诊断处理器给了我以下警告:

Event 'listener.DatabaseUnpublished' should not be subscribed with the same 'listener.DatabaseUnpublished' object.

所以我试着理解这里出了什么问题。 并尝试找出如何更改代码。

可能它解决了警告:

public void UnPublishDatabases(IReadOnlyCollection<IPublishedDatabase> sqlDatabases)
{
    var listener = new UnpublishDatabaseListener();
    //save ref
    var listenerCopy = listener;
    listener.DatabaseUnpublished += db =>
    {
        OnDatabaseUnpublished(db); 
        //use it
        listenerCopy.DatabaseUnpublished -= OnDatabaseUnpublished;
    };

    _publishController.Unpublish(sqlDatabases, listener);
    //...
}

我还有一个问题 - 我真的需要在这里退订吗? 因为监听器只是一个本地对象。

更新:

public class UnpublishDatabaseListener
{
    public event Action<IPublishedDatabase> DatabaseUnpublished;
    //...
}

【问题讨论】:

  • 那些是自定义类型吗?我不熟悉
  • 是的。它们是自定义类型
  • 我也对处理程序中的调用感到困惑。能否展示一下与此问题相关的UnpublishDatabaseListener 成员。
  • 旁注:var listenerCopy = listener; 正如你所说的 copy,这是否意味着 UnpublishDatabaseListener 是一个结构?
  • @Nkosi 我已经更新了我的代码

标签: c# .net events lambda anonymous-function


【解决方案1】:

将委托存储在一个变量中,以便在 lambda 处理程序中使用它来订阅和取消订阅。

public void UnPublishDatabases(IReadOnlyCollection<IPublishedDatabase> sqlDatabases) {
    var listener = new UnpublishDatabaseListener();
    Action<IPublishedDatabase> handler = delegate { };
    handler = db => {
        OnDatabaseUnpublished(db); 
        //unsubscribe
        listner.DatabaseUnpublished -= handler;
    };
    //subscribe
    listener.DatabaseUnpublished += handler;

    _publishController.Unpublish(sqlDatabases, listener);
    //...
}

【讨论】:

  • 好的,让我试试这个方法。顺便说一句,使用 lambda 和 delegate 有什么区别?
  • @isxaker 我把委托放在那里,这样处理程序就不会是null。我可以很容易地声明Action&lt;IPublishedDatabase&gt; handler = null;。想要确保分配了变量。否则会出现语法错误。这是我不久前学到的一种模式。
  • 是的,当然我现在该怎么做))但我的问题是使用 lambda 和命名委托有什么区别?我的意思是,委托的主体可能会在侦听器的实际引用中立即创建。如果使用 lambda,那有什么问题?
  • 我在想,对 lambda 的引用。让变量给出一个硬引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2017-06-19
相关资源
最近更新 更多