简体   繁体   English

列表<MyObject>不包含 GetAwaiter 的定义

[英]List<MyObject> does not contain a definition for GetAwaiter

I have a method that returns a List<> of an object.我有一个返回对象的 List<> 的方法。 This method takes a while to run.此方法需要一段时间才能运行。

private List<MyObject> GetBigList()
{
    ... slow stuff
}

This method is called from 4 or 5 sources.从 4 或 5 个来源调用此方法。 So, I thought I would try and use async and await to keep things moving while this list builds.所以,我想我会尝试使用 async 和 await 在这个列表构建时保持事情的进展。 I added this method:我添加了这个方法:

public async Task<List<MyObject>> GetBigListAsync()
{
    var resultsTask = GetBigList();
    var resuls = await resultsTask;
    return resuls;
}

But, on this line:但是,在这一行:

var resuls = await resultsTask;

I get this error:我收到此错误:

List<MyObject> does not contain a definition for GetAwaiter, and no extension method 'GetAwaiter' accepting a first argument of type List<MyObject> could be found. List<MyObject> 不包含 GetAwaiter 的定义,并且找不到接受 List<MyObject> 类型的第一个参数的扩展方法“GetAwaiter”。

What am I missing?我错过了什么?

It seems you're a newbee to async-await.看来你是 async-await 的新手。 What really helped me to understand what async-await does is the restaurant analogy given by Eric Lippert in this interview.真正帮助我理解 async-await 的作用是 Eric Lippert 在这次采访中给出的餐厅类比 Search somewhere in the middle for async await.在中间的某个地方搜索异步等待。

Here he describes that if a cook has to wait for something, instead of doing nothing he starts looking around to see if he can do something else in the meantime.在这里,他描述了如果厨师必须等待某事,而不是什么都不做,他会开始环顾四周,看看在此期间他是否可以做其他事情。

Async-await is similar.异步等待类似。 Instead of awaiting for a file to be read, a database query to return, a web page to be downloaded, your thread will go up the callstack to see if any of the callers are not awaiting and performs those statements until he sees an await.不是等待读取文件、返回数据库查询、下载网页,您的线程将进入调用堆栈以查看是否有任何调用者没有等待并执行这些语句,直到他看到等待。 Once he sees the await the thread goes up the call stack again to see if one of the callers is not awaiting etc. After a while when the file is read, or the query is finished etc, the statements after the await are performed.一旦他看到 await 线程再次上升调用堆栈以查看调用者之一是否不在等待等。在读取文件或查询完成等一段时间后,执行等待之后的语句。

Normally while reading your big list your thread would be very busy instead of idly waiting.通常,在阅读大列表时,您的线程会非常忙,而不是无所事事地等待。 It's not certain that ordering another thread to do the stuff would improve the time needed to read your list.不确定订购另一个线程来做这些事情会增加阅读列表所需的时间。 Consider measuring both methods.考虑测量这两种方法。

One reason to use async-await, even if it would lengthen the time needed to read the big list, would be to keep the caller (user interface?) responsive.使用 async-await 的一个原因,即使它会延长读取大列表所需的时间,也是保持调用者(用户界面?)响应。

To make your function async, you should do the following:要使您的函数异步,您应该执行以下操作:

  • Declare the function async;声明函数异步;
  • Instead of TResult return Task<TResult> and instead of void return Task ;而不是TResult返回Task<TResult>而不是void返回Task
  • If your function calls other async functions, consider remembering the returned task instead of await , do other useful stuff you need to do and await the task when you need the result;如果您的函数调用其他异步函数,请考虑记住返回的任务而不是await ,做其他您需要做的有用的事情并在您需要结果时await任务;
  • If you really want to let another thread do the busy stuff.如果你真的想让另一个线程做一些忙碌的事情。 call打电话

    Task.Run( () => GetBigList()) Task.Run(() => GetBigList())

and await when you need the results.并在需要结果时等待。

private async Task<List<MyObject>> GetBigListAsync()
{
    var myTask = Task.Run( () => GetBigList());
    // your thread is free to do other useful stuff right nw
    DoOtherUsefulStuff();
    // after a while you need the result, await for myTask:
    List<MyObject> result = await myTask;

    // you can now use the results of loading:
    ProcessResult(result);
    return result;
}

Once again: if you have nothing useful to do while the other thread is loading the List (like keeping UI responsive), don't do this, or at least measure if you are faster.再说一遍:如果在另一个线程加载 List 时您没有任何有用的事情可做(例如保持 UI 响应),请不要这样做,或者至少衡量一下您是否更快。

Other articles that helped me understanding async-await were - Async await , by the ever so helpful Stephen Cleary, - and a bit more advanced: Async-Wait best practices .其他帮助我理解 async-await 的文章是 - Async await ,作者是非常有帮助的 Stephen Cleary - 以及更高级的: Async-Wait best practice

resultTask is just the list returned from GetBigList() , so nothing will happen async there. resultTask只是从GetBigList()返回的列表,因此那里不会发生任何异步事件。

What you can do is offload the task to a separate thread on the threadpool by using Task.Run and return the awaitable Task object:您可以做的是使用Task.Run将任务卸载到线程Task.Run的单独线程并返回可等待的Task对象:

// Bad code
public Task<List<MyObject>> GetBigListAsync()
{
    return Task.Run(() => GetBigList());
}

While above example best matches what you were trying to do, it is not best practice.虽然上面的例子最符合你想要做的,但这不是最佳实践。 Try to make the GetBigList() async by nature or if there really is no way, leave the decision about executing the code on a separate thread to the calling code and don't hide this in the implementation Fe if the calling code already runs async, there is no reason to spawn yet another thread.尝试使GetBigList()本质上异步,或者如果真的没有办法,将在单独线程上执行代码的决定留给调用代码,如果调用代码已经异步运行,则不要在实现 Fe 中隐藏它,没有理由产生另一个线程。 This article describes this in more detail. 这篇文章更详细地描述了这一点。

几年后,但我觉得值得为集合添加,一旦人们搜索分辨率,因为 .NET 已经发生了很大变化:

return await Task.FromResult(GetBigList())

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

相关问题 async/await &quot;List&lt;&gt; 不包含 &#39;GetAwaiter&#39; 的定义&quot; - async/await "List<> does not contain a definition for 'GetAwaiter'" 不包含&#39;GetAwaiter&#39;的定义 - does not contain a definition for 'GetAwaiter' 列表<order> ' 不包含 'GetAwaiter' 的定义</order> - List<order>' does not contain a definition for 'GetAwaiter' Task<> 不包含“GetAwaiter”的定义 - Task<> does not contain a definition for 'GetAwaiter' “bool”不包含“GetAwaiter”的定义 - 'bool' does not contain a definition for 'GetAwaiter' &#39;ArrayList&#39;不包含&#39;GetAwaiter&#39;的定义 - 'ArrayList' does not contain a definition for 'GetAwaiter' IQueryable不包含GetAwaiter的定义 - IQueryable does not contain definition for GetAwaiter 不包含“GetAwaiter”的定义,并且没有可访问的扩展方法“GetAwaiter”接受“List”类型的第一个参数 - does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'List HttpResponseMessage' 不包含 'GetAwaiter' 的定义,并且没有可访问的扩展方法 'GetAwaiter' - HttpResponseMessage' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' WebAPI:“ IHttpActionResult”不包含“ GetAwaiter”的定义 - WebAPI : 'IHttpActionResult' does not contain a definition for 'GetAwaiter'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM