簡體   English   中英

如何從異步方法中獲取對象?

[英]How to get an object from an asynchronous method?


如何從異步方法中獲取對象?

描述
我正在嘗試做一個類似的項目。
項目鏈接- 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 => 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 => 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。##

根據答案的材料:馬丁。 關聯

我正在使用該方法。

 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 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 (); (類ICustomerRepositoryAnsw.GetCustomersTask1 () );
我按F11。
我進入字符串string result =" "; (類TestAnsw方法GetCustomersTask_Test() (此方法調用ICustomerRepositoryAnsw.GetCustomersTask1() )。
結果:調試不執行字符串result = results.FirstOrDefault (); return result;

題。
1.為什么行result = results.FirstOrDefault (); return result; 沒有被執行?

圖片1 在此處輸入圖片說明

圖2 在此處輸入圖片說明

模板async/await有很好的文檔 - 這里(我已經在上面的評論中寫過)。
作為總結,我可以說:
Task <T>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();

然后它將運行非阻塞異步。

實體框架核心

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM