【问题标题】:Want to unsubscribe async method inside Dispose function of blazor想要取消订阅 blazor 的 Dispose 函数中的异步方法
【发布时间】:2020-02-27 08:36:47
【问题描述】:

我在 Blazor 中使用事件将数据从一个局部视图传递到另一个视图。

问题:dispose 不起作用,每次页面销毁并重新呈现时,它都会附加相同的事件。当我调用事件时,它会调用多次(部分视图销毁和重新创建的时间)

带有调用方法的事件定义代码

public event Action<long,long,bool,bool> MyEvent;
public void InVokeMyEvent(long data1,
        bool data2,long data3,bool data4) {
        MyEvent?.Invoke(data1,data2,data3, data4);
    } 

函数定义

async Task MyFunction(long data1,
        long data2,
        bool data3,
        bool data4)
{}

我在 OnInitializedAsync 函数中注册事件如下。

protected override async Task OnInitializedAsync()
{

    RGEState.MyEvent+= async (long data1,
       long data2,
       bool data3,
       bool data4) =>
   await MyFunction(data1,
        data2,
        data3,
        data4);

    await base.OnInitializedAsync();
}

现在要分离事件,我在实现 IDisposable 后在页面中执行以下代码。

public void Dispose()
{
    RGEState.MyEvent -= async (long data1,
       long data2,
       bool data3,
       bool data4) =>
   await MyFunction(data1,
        data2,
        data3,
        data4);
}

【问题讨论】:

  • 我知道这看起来很傻,但是您的组件是否通过 @implements 指令实现了 IDisposable
  • 是的,我已经通过@Implements 指令实现了IDisposable。
  • 您的事件有什么异步的原因吗?一般来说,不能等待事件。
  • 这个方法调用数据库来获取一些数据。我想在数据库调用发生时显示进程指示器(加载器),所以我将此方法设为异步,并通过使用带有 StateHasChanged 方法的布尔变量 true/false,我可以轻松地显示隐藏加载器。

标签: blazor blazor-server-side asp.net-blazor


【解决方案1】:

Jon Skeet How to remove a lambda event handler 已在此回答了这个问题

基本上创建一个委托并使用它来订阅/取消订阅事件。

编辑以帮助 OP 理解

像这样 - 您需要保留对表达式的引用,以便在取消订阅时它是同一个委托。

private Action<long,long,bool,bool> _delegate;
protected override async Task OnInitializedAsync()
{

    _delegate = async (long data1,
       long data2,
       bool data3,
       bool data4) => await MyFunction(data1,
        data2,
        data3,
        data4);

    RGEState.MyEvent += _delegate;
    await base.OnInitializedAsync();
}

public void Dispose()
{
    RGEState.MyEvent -= _delegate;
}

【讨论】:

  • 感谢您的回复,我也在做同样的事情,它与同步方法工作正常,但它不适用于异步方法,因为它不会取消订阅 IDisposable 上的事件。
  • 那么您上面的代码并没有显示您这样做 - 也许您可以使用该代码更新它?
【解决方案2】:

我不确定我是否理解问题所在。此行为是设计使然... 创建组件时,将执行 OnInitializedAsync 方法,并将事件处理程序附加到 MyEvent 事件。当组件被销毁时,事件处理程序被分离。如果您的组件被重新创建,则上述过程将再次重复......一次又一次。您希望事件处理程序只添加一次吗?那是你要的吗 ?也许您应该以不同的方式设计您的组件。

但是,也许实现 CircuitHandler 对象可以解决您的问题,因为它涉及电路连接的生命周期。 See my answer here how to do it...

【讨论】:

    【解决方案3】:

    See following example

    根据上面的链接,我将函数“MyFunction”同步并在其中为加载程序调用了另一个异步函数

    void MyFunction(long data1,
            long data2,
            bool data3,
            bool data4)
    {
       InvokeAsync(async () => { await SecondFunction(data1, data2, data3, data4); });
    }
    async Task SecondFunction(long data1,
            long data2,
            bool data3,
            bool data4)
    {
     isLaoder = True;
     StateHasChanged ();
    
    /****Calling DB ***/
    
    isLaoder = False;
    StateHasChanged ();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-02
      • 2017-04-25
      • 2019-10-20
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 2019-05-06
      • 1970-01-01
      • 2014-08-26
      相关资源
      最近更新 更多