【问题标题】:How to get an object from an asynchronous method?如何从异步方法中获取对象?
【发布时间】:2020-03-26 12:39:20
【问题描述】:

问题
如何从异步方法中获取对象?

说明
我正在尝试做一个类似的项目。
项目链接 - Link // github.com ;
我尝试重复该方法-GetPosts (int index, int pageSize, string tag = null)

public async Task<Page<Post>> GetPosts(int index, int pageSize, string tag = null)
    {
        var result = new Page<Post>() { CurrentPage = index, PageSize = pageSize };

        using (var context = ContextFactory.CreateDbContext(ConnectionString))
        {
            var query = context.Posts.AsQueryable();
            if (!string.IsNullOrWhiteSpace(tag))
            {
                query = query.Where(p => p.Tags.Any(t => t.TagName == tag));
            }

            result.TotalPages = await query.CountAsync();
            result.Records = await query.Include(p => p.Tags).Include(p => p.Comments).OrderByDescending(p => p.CreatedDate).Skip(index * pageSize).Take(pageSize).ToListAsync();
        }

        return result;
    }

我想用任意请求创建一个类似的异步方法。
例如一个查询:query = query.Where (p =&gt; p.ContactName.Contains (" Maria "));.
我尝试做一个简单的方法:

public Customer GetCustomers ()
{
    Customer result = new Customer ();
 
    using (var context = ContextFactory.CreateDbContext (ConnectionString))
    {
      var query = context.Customers.AsQueryable ();
      query = query.Where (p => p.ContactName.Contains ("Maria")); //
      result = query as Customer;
    }
    return result;
}

 
字符串query = query.Where (p =&gt; p.ContactName.Contains (" Maria "));中的结果见图。

问题。
如何使这样的方法与相同或不同的请求异步?

尝试次数 - 1. 结果 - 无效。

public Task <Customer> GetCustomersTask ()
        {
            // Customer result = new Customer ();
 
            var result = new TaskCompletionSource <Customer> ();
 
            using (var context = ContextFactory.CreateDbContext (ConnectionString))
            {
                Task.Run (() =>
                {
                    var query = context.Customers.AsQueryable ();
                    query = query.Where (p => p.ContactName == "Maria");
 
                    result.SetResult (query as Customer);
                }
                );
            }
            return result.Task;
        }

图片1

图片2


更新 1。##

根据答案的材料:马丁。 link

我正在使用该方法。

 public async Task <Customer> GetCustomerAsync ()
{
    Customer result = new Customer ();

    using (var context = ContextFactory.CreateDbContext (ConnectionString))
    {
      var query = context.Customers.AsQueryable ();
      query = query.Where (p => p.ContactName.Contains ("Maria")); //
      var results = await query.ToListAsync ();
      result = results.FirstOrDefault ();
    }
    return result;
}

我收到一个错误:
“IQueryable”不包含“ToListAsync”的定义, 并且找不到可用的扩展方法“ToListAsync”, 主机类型“IQueryable”作为第一个 参数(可能使用指令或程序集引用缺失)。

图片1


更新 2

using Microsoft.EntityFrameworkCore;添加。
现在类命名空间的形式为:
using DBRepository.Interfaces;
using Models;
using System;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.EntityFrameworkCore;

错误(参见 Update-1):
"IQueryable" does not contain a definition of "ToListAsync", and could not find an available extension method "ToListAsync", host type "IQueryable" as the first argument (possibly using directive or assembly reference missing). 消失了。

说明。
我正在调试。
我进入字符串var results = await query.ToListAsync ();(of classICustomerRepositoryAnsw.GetCustomersTask1 ());
我按 F11。
我进入字符串string result =" ";(类TestAnsw方法GetCustomersTask_Test()(此方法调用ICustomerRepositoryAnsw.GetCustomersTask1())。
结果:调试不执行字符串result = results.FirstOrDefault ();return result;

问题。
1、为什么result = results.FirstOrDefault ();return result;这行没有执行?

图片1

图片2

【问题讨论】:

  • 您是否有理由不简单地使用 async/await 模式而不是 TaskCompletionSource。有一个写得很好的答案here
  • @Martin 1. Is there a reason why you are not simply use async/await pattern instead of the TaskCompletionSource. 这是个问题吗?不,我只是想弄清楚如何制作一个异步工作并返回我需要的结果的方法。 2. 我正在研究你的链接。
  • 对不起,我错过了问号,这是一个问题。我发布了一个可能的答案。也许这会对你有所帮助。
  • GetCustomersTask1 需要等待,因为它是一个异步方法。您可以在“原始视图”中看到这里只有TaskSee documentation of await

标签: c# linq .net-core entity-framework-core


【解决方案1】:

模板上有很好的文档async/await - here(我已经在上面的评论中写过)。
作为总结,我可以说:
Task &lt;T&gt;async NOT 使方法异步。
只有await 关键字使方法异步。

因此,如果您希望方法以非阻塞方式运行,则必须对 EntityFramework 使用异步 API/Framework 调用。

public Task<Customer> GetCustomerAsync ()
{
    Customer result = new Customer ();

    using (var context = ContextFactory.CreateDbContext (ConnectionString))
    {
      var query = context.Customers.AsQueryable ();
      query = query.Where(p => p.ContactName.Contains ("Maria")); //
      result = query.FirstOrDefault();
    }
    return Task.FromResult(result);
}

看起来是异步的,但不是

但是如果你使用扩展方法.ToListAsync()

public async Task<Customer> GetCustomerAsync ()
{
    Customer result = new Customer ();

    using (var context = ContextFactory.CreateDbContext (ConnectionString))
    {
      var query = context.Customers.AsQueryable ();
      query = query.Where (p => p.ContactName.Contains ("Maria")); //
      var results = await query.ToListAsync();
      result = results?.FirstOrDefault();
    }
    return result;
}

现在您可以通过以下方式调用此实现:

var customer = await YourClass.GetCustomerAsync();

Then it will run non-blocking async.

EntityFramework Core

【讨论】:

  • 我不太明白你的回答。 1. 你的意思是我需要使用Framework 应用程序吗? 2. 你有没有注意到我使用了.net-core,` entity-framework-core? Or your solution for .net-Framework`? 3.var results = await query.ToListAsync () 行中出现错误:"IQueryable &lt;Customer&gt;" does not contain a definition of “ToListAsync”, and could not find an available extension method "ToListAsync", host type "IQueryable &lt;Customer&gt;" as the first argument (possibly using using directive or assembly reference). 请参阅Update-1
  • 1.使用 EF 或其他 SDK 的 [...]Async() 方法。 2. 是的,因此我还通过直接链接到 EF Core 更新了我的答案。 3. 也许你必须为这个扩展方法添加一个using
  • Update-2. 添加using Microsoft.EntityFrameworkCore;。错误已消失。结果:调试不执行字符串result = results.FirstOrDefault ();return result;Question. ** 1. **为什么没有执行result = results.FirstOrDefault ();return result;行?
  • 我更新了你的答案。我进行了更正,我认为这将使您的答案更容易理解(听起来更好)。我不太懂英语,所以如果我对答案的解释对您来说不正确,我深表歉意。如果您认为您对答案的解释更好,那么您可能应该留下您的答案选项。
猜你喜欢
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
相关资源
最近更新 更多