繁体   English   中英

为什么我不能在我的 Web ZDB974238714CA814F14Z 项目中使用带有 C# 异步 function 的 Discard 作为一个 forget 和 fire 机制

[英]Why can't I use a Discard with C# async function in my Web API project as a fire and forget mechanism

我正在编写一个 Web API 项目,对于我的一个端点( HandleAsync方法是实现)我无法使用丢弃语法( _ ),我不知道为什么。

我还有其他地方采用相同的模式:调用CheckoutFileAsync并且在processNotifications委托中我可以在调用SendEmailAsync时使用_

唯一的区别是IfContentManagementAuthorizedAsync而不是IfFileActionAuthorizedAsync的不同条目,但是如果授权逻辑中的一切都很好,则每个条目都具有异步回调的“相同”概念。

我收到的编译错误在这一行

_ = emailService.SendEmailAsync(

这是错误:

无法将类型“System.Threading.Tasks.Task”隐式转换为“bool”

如果我在_上使用 hover ,智能感知会说(parameter) bool _ 如果我 hover 在_上工作,它会说(discard) Task<bool> _

我基本上想要一个“即发即弃”机制来发送通知 email。 我不想处理结果或等待可能发生的任何延迟,据我了解,丢弃语法是我应该做的模式。 鉴于下面的代码,您是否看到我不能使用丢弃语法的任何原因?

请注意,我有两个If*AuthorizedAsync方法的重载,一个返回Task<IActionResult>另一个返回Task<ActionResult<T>>因为它们用于我的所有端点,它们的返回类型不同,我无法弄清楚如何使一个签名适用于所有端点。

public async Task<IActionResult> HandleAsync( [FromQuery] FileIdParameters parameters )
{
    var fileInfo = await GetFilePropertiesAsync<DataLockerFile>( parameters.Id, null );

    if ( fileInfo == null )
    {
        return NotFound();
    }

    return await IfFileActionAuthorizedAsync(
        "Write",
        fileInfo.FolderName,
        async ( user, userEmail, canCreateFolder ) =>
            await CheckoutFileAsync(
                userEmail,
                fileInfo,
                dateTimeService.UtcNow,
                fileInfo =>
                {
                    _ = emailService.SendEmailAsync(
                        string.Join( ";", notificationEmails ),
                        emailService.DefaultFrom,
                        $"KAT Management Secure File Checkout: {fileInfo.FolderName}:{fileInfo.Name}",
                        $"{user} has checked out {fileInfo.FolderName}:{fileInfo.Name}."
                    );
                }
            )
    );
}

protected async Task<ActionResult<T>> IfFileActionAuthorizedAsync<T>(
    string requiredClaim, string folder,
    Func<string, string, bool, Task<ActionResult<T>>> validResult )
{   
    var claimResult = Foo(); // .. logic 
    return await validResult( claimResult.User, claimResult.UserEmail, claimResult.CanCreateFolder );
}
protected async Task<IActionResult> IfFileActionAuthorizedAsync(
    string requiredClaim, string folder,
    Func<string, string, bool, Task<IActionResult>> validResult )
{   
    var claimResult = Foo(); // .. logic 
    return await validResult( claimResult.User, claimResult.UserEmail, claimResult.CanCreateFolder );
}

protected async Task<IActionResult> CheckoutFileAsync(
    string userEmail,
    DataLockerBaseFile fileInfo,
    DateTime checkoutTime,
    Action<DataLockerBaseFile> processNotifications
)
{
    var fileInfo = await DoSomethingAsync(); // logic

    processNotifications( fileInfo );

    return Ok();
}

// This method is part of another class, the smtp configuration object is inject with DI
public async Task<bool> SendEmailAsync( string to, string from, string subject, string body )
{
    var message = CreateMailMessage( to, from, subject body );

    var mailClient = new SmtpClient( smtp.Server );
    mailClient.Credentials = new System.Net.NetworkCredential( smtp.UserName, smtp.Password );
    await mailClient.SendMailAsync( message );

    return true;
}

IntelliSense 悬停表示问题:

如果我在 _ 上使用 hover,智能感知会说(parameter) bool _

导致此问题的代码使用一种通用模式来处理排序但并非真正丢弃的参数值,其中之一是bool 例如,它可能有一些 lambda 的形式(arg, _ /* unneeded boolean argument */) => {... } 附带说明一下,您发布的代码没有这种模式,也不会导致问题; 在简化要发布的代码时,请确保您最终发布的代码确实重现了问题。

这是表示“不需要此参数”的常见模式; 但是,这并不是语言级别的实际丢弃(C# 9.0 中的某些情况除外) 相反,它实际上定义了一个名为_的类型为bool的参数。

因此,丢弃模式_ =...不适用于该代码块。 由于有一个名为_的实际参数,编译器将其视为对该参数的赋值,并给出错误:

无法将类型“System.Threading.Tasks.Task”隐式转换为“bool”

解决方案是将 sort-of-discard 参数从_重命名为__ 然后丢弃模式将起作用。

另一方面, “即发即弃”几乎总是错误的解决方案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM