【问题标题】:Cannot await 'long' when calling an async method inside asp.net mvc5在 asp.net mvc5 中调用异步方法时无法等待“长”
【发布时间】:2015-09-06 01:39:57
【问题描述】:

我的 EF6 的 asp.net mvc 5 Web 应用程序中有以下异步方法:-

public async Task<Resource> GetResourceByName(string resourcename)
        {
            return await entities.Resources.SingleOrDefaultAsync(a => a.RESOURCENAME.ToLower() == resourcename.ToLower());

        }

现在我正在尝试从上述方法中获取返回对象的 ID,如下所示:-

 var temp = await GetResourceByName(FQDN).Result.RESOURCEID;

但这会引发以下错误:-

错误 1 ​​无法等待“长”

现在要解决这个问题,我做了以下事情:-

var temp = await GetResourceByName(FQDN);


id = temp.RESOURCEID;

所以不知道为什么我的第一个方法不起作用。现在我等待任务,当它完成时,我将检索 .Result 并获取 ResourceID ...那为什么这不起作用?

这里是资源的模型:-

 public partial class Resource
    {
        public long RESOURCEID { get; set; }
        public string RESOURCENAME { get; set; }
        public Nullable<long> ACQUISITIONDATE { get; set; }
        public Nullable<long> WARRANTYEXPIRY { get; set; }
        public Nullable<long> EXPIRYDATE { get; set; }
        public long COMPONENTID { get; set; }
        public string ASSETTAG { get; set; }
        public string SERIALNO { get; set; }
        public string BARCODE { get; set; }
        public Nullable<long> PURCHASELOTID { get; set; }
        public Nullable<long> VENDORID { get; set; }
        public long RESOURCESTATEID { get; set; }
        public Nullable<long> SITEID { get; set; }
        public Nullable<long> CIID { get; set; }
        public bool ISDEPRECIATIONCONFIGURED { get; set; }
        public bool ISDEPRECIATIONCALCULATED { get; set; }
        public bool ISPERSONAL { get; set; }

        public virtual ComponentDefinition ComponentDefinition { get; set; }
        public virtual ResourceLocation ResourceLocation { get; set; }
        public virtual ResourceState ResourceState { get; set; }
        public virtual SiteDefinition SiteDefinition { get; set; }
    }

【问题讨论】:

    标签: asp.net .net asp.net-mvc asynchronous entity-framework-6


    【解决方案1】:

    等待任务会给你结果。如果你想下降到结果的属性,如果你想在一个表达式中全部使用括号,则需要使用括号:

    var temp = (await GetResourceByName(FQDN)).RESOURCEID;
    

    【讨论】:

    • 感谢您的回复,但正在编写以下正确的“it360id = GetResourceByName(FQDN).Result.RESOURCEID”???或者最好写“var temp = (await GetResourceByName(FQDN)).RESOURCEID;”正如你提到的?
    • @johnG:不,你不应该使用Result。请改用await
    • 但为什么我应该使用 await 而不是 Result ?第二个问题是我将调用存储在临时变量中的一种好方法:-“var temp = await GetResourceByName(FQDN); id = temp.RESOURCEID;”
    • @johnG:我在我的博客上描述了one reason not to block on async code。一个更根本的原因是,在 ASP.NET 上,无论何时阻塞,您首先都放弃了异步代码的所有优势。关于 temp 变量,当然,这很好。
    【解决方案2】:

    在任务上调用.Result 会阻塞线程,直到操作完成。结果对象是在TResult 中为任务指定的类型。

    您的电话无效,因为您不能等待任务的结果,只能等待任务本身。一旦您致电.Result,就没有什么可等待的了。

    【讨论】:

    • 所以你的意思是这应该是正确的“it360id = GetResourceByName(FQDN).Result.RESOURCEID;” ??并使用 .Result 将等待调用?
    • 调用.Result 是有风险的,如果使用不当可能会导致死锁。您可以在 Stephen Cleary 的 blog 上阅读更多相关信息
    • 那么我应该怎么写呢?所以你的意思是使用 await 没有风险,而使用 .Result 可能会导致死锁?
    • 您使用temp 变量实现它的方式很好。
    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多