与此方法相比,将 L2S 与新的 C# 5async/await
关键字一起使用的最佳实践是什么?在网上找不到任何东西。
2 回答
EF 5 没有 async/await 支持,但开源版本正在积极探索这里的可能性。编辑:EF 中的异步支持记录在http://msdn.microsoft.com/en-us/data/jj819165.aspx。它不会将结果流式传输,因为它们是水合的(正如您在 RX 中会发现的那样),但它确实使数据库调用异步。
至于 LINQ to SQL,除了将您的请求包装在 Task.Factory.Start 操作中之外,我不会屏住呼吸,希望 Microsoft 为 Linq to SQL 实现基于任务的异步(异步/等待所需)。
如果绝对必要,您可以使用IQToolkit并扩展它,添加您自己的异步支持。此外,Mono 已经实现了 LINQ to SQL,您可以使用异步支持对其进行扩展。
Scott Hanselman 有一篇有趣的文章,他在其中演示了如何在现有的 Linq to SQL 查询之上生成异步 API。我没有时间玩这个想法,但我猜测可以创建一个更通用的扩展方法,它允许将相同的技术扩展到任何 IQueryable 或 IEnumerable 类型的对象。
这是直接来自他的帖子的代码,可用作参考。
SqlCommand _beginFindCmd = null;
public IAsyncResult BeginFind(int id, AsyncCallback callback, Object asyncState)
{
var query = from w in _db.Widgets
where w.Id == id
select w;
_beginFindCmd = _db.GetCommand(query) as SqlCommand;
_db.Connection.Open();
return _beginFindCmd.BeginExecuteReader(callback, asyncState, System.Data.CommandBehavior.CloseConnection);
}
public Widget EndFind(IAsyncResult result)
{
var rdr = _beginFindCmd.EndExecuteReader(result);
var widget = (from w in _db.Translate<Widget>(rdr)
select w).SingleOrDefault();
rdr.Close();
return widget;
}
只需做一些工作,就可以使这个 TPL 变得更简洁,并且作为一个单一的异步方法。如果我有机会这样做,我会发布我的想法。