无法从 Task<> 隐式转换类型
Posted
技术标签:
【中文标题】无法从 Task<> 隐式转换类型【英文标题】:Cannot implicitly convert type from Task<> 【发布时间】:2012-10-04 21:24:19 【问题描述】:我正在尝试掌握 .NET 4.5 中的异步方法语法。我以为我已经完全理解了这些示例,但是无论异步方法的类型是什么(即Task<T>
),在转换回T
时我总是会遇到相同类型的错误错误——我理解的差不多自动的。以下代码产生错误:
无法将类型“
System.Threading.Tasks.Task<System.Collections.Generic.List<int>>
”隐式转换为“System.Collections.Generic.List<int>
”
public List<int> TestGetMethod()
return GetIdList(); // compiler error on this line
async Task<List<int>> GetIdList()
using (HttpClient proxy = new HttpClient())
string response = await proxy.GetStringAsync("www.test.com");
List<int> idList = JsonConvert.DeserializeObject<List<int>>();
return idList;
如果我也明确地转换结果,它也会失败。这个:
public List<int> TestGetMethod()
return (List<int>)GetIdList(); // compiler error on this line
在某种程度上会导致此错误:
无法将类型“
System.Threading.Tasks.Task<System.Collections.Generic.List<int>>
”转换为“System.Collections.Generic.List<int>
”
非常感谢任何帮助。
【问题讨论】:
Task您的示例的主要问题是您无法将 Task<T>
返回类型隐式转换为基本 T
类型。您需要使用 Task.Result 属性。请注意,Task.Result 将阻塞异步代码,应谨慎使用。
试试这个:
public List<int> TestGetMethod()
return GetIdList().Result;
【讨论】:
Result
could easily cause deadlocks.
完美运行
@Stephen Cleary 真的
它可以完美运行,直到死锁。【参考方案2】:
您还需要创建 TestGetMethod async
并在 GetIdList();
前面附加 await 会将任务解包到 List<int>
,因此,如果您的辅助函数返回 Task,请确保您在调用函数时已等待 @ 987654324@也是。
public Task<List<int>> TestGetMethod()
return GetIdList();
async Task<List<int>> GetIdList()
using (HttpClient proxy = new HttpClient())
string response = await proxy.GetStringAsync("www.test.com");
List<int> idList = JsonConvert.DeserializeObject<List<int>>();
return idList;
另一种选择
public async void TestGetMethod(List<int> results)
results = await GetIdList(); // await will unwrap the List<int>
【讨论】:
请注意,因为在这个 TestGetMethod 中没有其他任何事情发生,所以 unwrap+rewrap 有点傻,它可以删除 async 和 await 并返回 GetIdList() :)TestGetMethod
必须是 async
有什么要求?【参考方案3】:
根据您要执行的操作,您可以使用 GetIdList().Result 阻止(通常是个坏主意,但很难说出上下文)或使用支持异步测试方法并具有测试方法 do var results = await GetIdList();
【讨论】:
【参考方案4】:我刚刚弹出了同样的问题,但解决方案与其他问题不同。我正在使用异步方法中的两个异步调用,这段代码给了我错误:
var fileContents = reader.ReadToEndAsync();
if (fileContents != null)
var profile = await Task.Run(() => JsonConvert.DeserializeObject<T>(fileContents));
return profile;
这是解决方法。我忘记了第一行的异步:
var fileContents = await reader.ReadToEndAsync();
if (fileContents != null)
var profile = await Task.Run(() => JsonConvert.DeserializeObject<T>(fileContents));
return profile;
错误消息显示在 var profile = ... 行的“fileContents”上,因此无法立即看出错误在哪里。
【讨论】:
以上是关于无法从 Task<> 隐式转换类型的主要内容,如果未能解决你的问题,请参考以下文章
不能隐式转换类型'System.Threading.tasks.task 至
无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”
无法将类型 IAsyncOperation<StorageFile> 隐式转换为 StorageFile