代码之家  ›  专栏  ›  技术社区  ›  USMC6072

在父事件处理程序中调用异步方法会引发错误

  •  0
  • USMC6072  · 技术社区  · 2 年前

    我的页面中有一个子组件,用于管理一些数据编辑。当我在子对象中单击“保存”时,它会引发一个在父对象中处理的事件。然后,父处理程序调用一个方法来获取我在父处理程序中需要的一些数据。在处理程序内部调用该方法是失败的地方。这是在孩子身上引发事件的地方

            private async void SaveEditChange(EditContext editContext)
            {
                <<does some stuff to get the return object ready>>
    
                await SaveEditRequestEvent.InvokeAsync(Request);
            }
    
    

    这是父处理程序。

           protected async void SaveEditRequestEvent(RequestDTO editedRequest)
            {
    
                var request =  await RequestDomain.GetRequestAsync(editedRequest.RequestId).ConfigureAwait(false);
    
                <<do some stuff with the request object>>
    
                NavManager.NavigateTo("/");
            }
    
    

    的呼叫 RequestDomain.GetRequestAsync(editedRequest.RequestId).ConfigureAwait(false); 是处理程序中发生的第一件事。该方法返回一个对象类型。当它尝试执行该方法时,它会故障返回到引发事件的子级

    enter image description here

    我读过的大多数文章都说,将方法调用封装在lambda调用中,如`InvokeAsync(()=>RequestDomain。GetRequestAsync(已编辑Request.RequestId)。ConfigureAwait(false))。然后我得到一个错误,它可以将“Action”转换为我返回的对象类型。

    我认为这与维护线程安全有关,但我不确定,我对此感到头疼。

    0 回复  |  直到 2 年前
        1
  •  1
  •   Henk Holterman    2 年前

    直接错误来自于使用 .ConfigureAwait(false) .

    这在服务中是一个合理的优化,但不应该在顶层UI代码中使用。无论是WinForms、MAUI还是Blazor。

    对于ConfigureAwait(false),您实际上是在说您不在乎代码恢复到哪个线程,但正如erorr所示,这确实很重要。

    此外,你还有两个 async void 方法。这会引起其他问题,不要那样做。所有Blazor生命周期和UI事件都可以返回 void 或异步 Task .