I am still an async/await novice, but I think I am getting a better grip on it. I am writing for suggestions on how to handle a certain scenario. The scenario is that, a certain web service has a method with both sync and async versions, but the versions have different return types.
getDocs()
returns document[]
, which is what I want.
getDocsAsync()
returns Task<getDocsResponse>
, where getDocsResponse
has a (non-awaitable) property of type document[]
.
To further complicate matters, I am calling this method inside a delegate I am passing to another method. (I am doing this so I can, at will, either get fresh data from the server, or use saved data that I have cached from earlier calls. The delegate that uses the saved data is basically Task.FromResult(myDocArray)
. Whether fresh or cached, I have more code that is going to process the document
objects.)
The main question is, if I call the async version, can I await the return value's property? If so, how? If not, do I have to wait for the result to get the property (as in, response.Result
)?
(Simplified) code sample: Call the sync method, but wrap in a task. This seems like it would work fine, and is what I would do if there wasn't an async version of the getDocs
method.
Func<Task<document[]>> f = async () => {
var docs = Task.Run(() => service.GetDocs());
return await docs;
}
(Simplified) code sample: Call the async version, but then ... ?
Func<Task<document[]>> f = async () => {
var docs = service.GetDocsAsync();
// this seems silly to call .Result, only to wrap it in an awaitable task.
return await Task.FromResult(docs.Result.documents);
}
Both versions appear to work fine, but in this case, the async route seems awkward. Is there a better way to handle such a case?
Thanks!
Do not use .Result
on task you did not await
as it in most cases lead to deadlock ( await vs Task.Wait - Deadlock? , await works but calling task.Result hangs/deadlocks )
I think you want to just return documents
from your async delegate:
Func<Task<document[]>> f = async () => {
Task<getDocsResponse> task = service.GetDocsAsync();
getDocsResponse response = await task;
return response.documents;
}
Note that result of the async method is always Task<>
of whatever type you return
. You don't need to wrap result in Task.FromResult
.
FromResult
is useful when you need to match Task<T>
signature but have only synchronous method. So synchronous call you have may be rewritten synchronously (unless you really need async code, but generally it is not recommended practice - What is the best way for wrapping synchronous code into asynchronous method )
Func<Task<document[]>> f = () => Task.FromResult(service.GetDocs());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.