罗马苏丹默罕默德

罗马苏丹默罕默德

CS1988|C#无法在异步方法中使用ref,in,out类型的参数

🌀|场景:

CS1988|C#无法在异步方法中使用ref,in,out类型的参数的问题-LMLPHP

BlazorServer的场景中推荐使用异步方法,使用ref,out,in为参数前缀则报错CS1988

原因如下:

⛵️|替代方法:

将需要用到的参数作为Task的返回,即

CS1988|C#无法在异步方法中使用ref,in,out类型的参数的问题-LMLPHP

💥|延申:引用变量的可见性

现有Blazor页面如下

@page "/login"

@using KatexTest2.Models
@using KatexTest2.Utils
@inject MyAuthProvider provider


<h3>LoginPage</h3>

<AuthorizeView>
    <NotAuthorized>
        
        @if(Isfailed){
            <span>用户名或密码错误</span>
        }
        
        @if (test.Number==114.514M)
        {
            <span>压力吗室内</span>
        }
        <EditForm id = "LP" Model="loginModel" Context="Login">
            <div>
                <label> Username: 
                    <InputText @bind-Value="loginModel.Username"></InputText>
                </label>
            </div>
            <div>
                <label> Password:
                    <InputText type="password" @bind-Value="loginModel.Password"></InputText>
                </label>
            </div>
            <div>
                <button @onclick="TryLogin">Submit</button>
            </div>
        </EditForm>    
    </NotAuthorized>
    <Authorized>
        <button type="button" class="btn btn-primary" @onclick="TryLogout" ></button>
    </Authorized>    
    <Authorizing>
        <span>翼沿丁真</span>
    </Authorizing>
</AuthorizeView>


@code {

    public class RefTest
    {
        public string Context { get; set; } = "DefaultContext";

        public decimal Number { get; set; } = 11.54M;
    }

    [Parameter]
    public Boolean Isfailed { get; set; } = false;

    public RefTest test { get; set; } = new();

    private LoginFormModel loginModel { get; set; } = new();

    private async Task TryLogin()
    {
        
       Isfailed  =  await provider.LoginAsync(loginModel,test);
        
    }

    private async Task TryLogout()
    {
        await provider.LogoutAsync();
    }
}

修改LoginAsync方法如下:

 public async Task<Boolean> LoginAsync(LoginFormModel loginFormModel,RefTest test)
{
    var (userInDatabase, isSuccess) = LookUpUser(loginFormModel.Username, loginFormModel.Password);
    var principal = new ClaimsPrincipal();

    if (isSuccess)
    {
        var identity = CreateIdentityFromUser(userInDatabase);
        principal = new ClaimsPrincipal(identity);
        await _protectedLocalStorage.SetAsync("identity", JsonConvert.SerializeObject(userInDatabase));
    }
    else
    {
        test.Number = 114.514M;
    }

    NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(principal)));

    await jsRuntime.InvokeVoidAsync("alert", new object[1] { "WTF" });

    return !isSuccess;
}

运行测试:

CS1988|C#无法在异步方法中使用ref,in,out类型的参数的问题-LMLPHP

从图中可以看出:

在方法的运行时间内,razor page并不能获取对象信息改变的值(运行完成后可以),如果是一些运行时间长的方法,则可能造成一些响应不及时的效果。例如拿掉权限后依旧可以访问一些东西

🔚|结论:

如果要在async方法中获取一些返回值,请直接加在的Task的返回中。

应避免使用引用类型为参数来充当返回值。

08-18 09:19