在我的数据访问层中,我正在尝试创建返回类型为Task的方法。
我无法从实体框架中获取返回类型以返回Task<List<MYtype>>
public static Task<List<ILeaf>> GetLeafs(int doorID)
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
}
使这种运行正确的唯一方法是格式化代码,如下所示:
public async static Task<List<ILeaf>> GetLeafs(int doorID)
{
return await Task.Run(() =>
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
});
}
我问的原因是因为我想提供运行异步的选项,还是我没有正确理解这个? 如果我可以返回一个Task然后在调用端,我可以选择等待,如果我想运行异步,但如果我想同步运行,我只是正常调用该方法。
如果我正在返回任务,我是否总是必须在方法签名中包含async关键字?
我是否以错误的方式思考这个问题?如果我有一个返回类型的任务,那么该方法可以选择被称为异步或同步吗?
但是,如果我在方法签名中有async和Task,那么该方法无论如何都会运行异步?
谢谢!
答案 0 :(得分:11)
所以要回答问题的字面问题,你可以这样做:
public static Task<List<ILeaf>> GetLeafs(int doorID)
{
return Task.Run(() =>
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
});
}
那说,请注意,这不是一个特别有用的方法。利用异步编程的想法是,你不希望线程池线程只是等待这个IO操作。理想情况下,您可以利用本质上异步的IO;一种本身自然返回任务的方法。
通过将阻塞IO包含在Task.Run
的调用中,您并没有真正为代码的使用者提供价值。如果他们需要在后台线程中运行该操作,他们可以自己完成,然后他们会更准确地知道它不是一个天真的异步操作。
有关此主题的详情,请参阅Should I expose asynchronous wrappers for synchronous methods?。
答案 1 :(得分:5)
public static async Task<List<ILeaf>> GetLeafs(int doorID)
{
using (var db = new StorefrontSystemEntities())
{
var result = db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
return await Task.FromResult(result);
}
}