当使用另一个剃须刀组件中的组件时,通常需要调用由EventCallback属性触发的异步方法,例如onClick.有什么特殊的方式调用它以确保异步性吗?

让我们假设下面的例子:

@* CASE 1*@
<MyButton OnClick=DoSomething>Click Me</MyButton>

@* CASE 2*@
<MyButton OnClick=@(async () => await DoSomething())>Click Me</MyButton>

@code {
    private async Task DoSomething(){ ... }
}

编译后,使用委托和直接调用函数有什么区别吗?我们应该 Select 一个还是另一个?

这个问题并不是由于错误或代码运行不正确而引起的,而只是因为我没有从Visual Studio获得反馈这一事实,而且可能是出于很好的原因,但我想知道我是否以任何一种方式编写了不正确的代码.

Select 备注:很难为所有人 Select 一个单一的答案,为讨论提供有效的观点,鼓励进一步阅读.这种混淆似乎源于对委托在调用堆栈中的角色的误解,在这种情况下,我认为Shaun的回答显示了最简洁和明确的例子.

推荐答案

在这个特定的情况下,第一个更好.

此代码块将任务包装在任务中.它浪费资源:每个任务都是一个状态机对象.

OnClick=@(async () => await DoSomething())>

然而,实际发生的情况取决于MyButton.

这是一个演示版本.我已经添加了两个按钮事件处理程序,每个按钮事件处理程序都有关于如何执行的注释.

<button @attributes=this.AdditionalAttributes @onclick=this.OnButtonClickAsync></button>

@code {
    [Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private async Task OnButtonClickAsync(MouseEventArgs e)
    {
        // you are awaiting the delegate in the parent component
        // if it yields you'll await it's completion
        await this.OnClick.InvokeAsync(e);
        // Code here will only execute after the parent delegate has completed, awaits and all
        // any exceptions will bubble up to here 
    }

    private void OnButtonClick(MouseEventArgs e)
    {
        // This is a Fire and Forget call
        this.OnClick.InvokeAsync(e);
        // code here will execute as soon as the parent delegate yields
        // exceptions won't bubble up to here
    }
}

更广泛地说,这是个人喜好的问题.

我喜欢干净的标记,所以我这样编写代码.

<button disabled="@buttonCss"></button>

@code {
    private bool _isDisabled;
    private string buttonCss => _isDisabled ? "btn btn-danger" : "btn btn-success";
}

其他人喜欢简洁的[内联]代码.

<button disabled="@(_isDisabled ? "btn btn-danger": "btn btn-success")"></button>

@code {
    private bool _isDisabled;
}

Asp.net相关问答推荐

在这个 For 循环计数没有增加

如何在 ASP.​NET Core 中使用 jquery

InvalidOperationException:在程序集上找不到UserSecretsIdAttribute

业务逻辑中的实体框架最佳实践?

asp.net:与其中的用户控件相比,控件/页面的页面生命周期顺序是什么?

控制器 SessionStateBehavior 是只读的,我可以更新会话变量

正在检索组件的 COM 类工厂......错误:80070005 访问被拒绝. (来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))

使用 JSON.NET 解析 json 字符串

如何从 URI 中删除 PROTOCOL

如何将 ASP.NET MVC5 身份验证添加到现有数据库

如何使用 ASP.Net MVC 路由来路由图像?

LINQ:使用 Lambda 表达式获取 CheckBoxList 的所有选定值

无法序列化会话状态

<%# Eval("State") %> 或 <%# DataBinder.Eval(Container.DataItem, "state")%>

如何忽略身份框架的魔力,只使用 OWIN 身份验证中间件来获取我寻求的声明?

为什么混合 Razor Pages 和 VueJs 是一件坏事?

路由模板分隔符/不能连续出现 - 属性路由问题

在 C# 中动态创建 Json

配置授权服务器端点

如何使用实体框架执行原始 SQL 查询而无需使用模型?