C# 是Oracle OpenAsync等。。。不是真正的异步方法?
我有一个通过ODP.NET访问的Oracle数据库 这是我的演示代码C# 是Oracle OpenAsync等。。。不是真正的异步方法?,c#,oracle,asynchronous,odp.net,C#,Oracle,Asynchronous,Odp.net,我有一个通过ODP.NET访问的Oracle数据库 这是我的演示代码 public static async Task<Field[][]> ReadAsync(string ExtractSql) { var connStr = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString; List<Field[]> ret = new List<Field[]
public static async Task<Field[][]> ReadAsync(string ExtractSql)
{
var connStr = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
List<Field[]> ret = new List<Field[]>();
using (OracleConnection conn = new OracleConnection(connStr))
{
await conn.OpenAsync();
}
return ret.ToArray();
}
一切正常。
我是否可以断定这是ODP.NET中的错误,是否存在github回购协议,或者在哪里可以报告它,或者我在C#async中遗漏了一些琐碎的东西
是否还有其他人在使用.NET for Oracle时遇到类似的异步方法问题
请注意
当然,我已经在里面添加了代码来打开命令并读取数据,问题仍然存在,在这里,我展示了足够检测问题的最小代码量。例如,我有一个防火墙,可以阻止连接,在这种情况下,它会超时,因此,如果db部分是非异步的,那么唯一的“打开”命令可以足够使应用程序卡住。感谢@madreflection的评论。我真的很高兴删除我的答案,并接受他的回答,正如我善意地问的那样 无论如何,现在通过查看VisualStudioIntelliSense可以清楚地看到,这些异步方法并不存在,但它们是从泛型
System.Data.Common.DbConnection
继承的
我也应该在第一个方法中理解它,该方法不返回任务
或任务
,即从下一行返回
OracleDataReader DR = (OracleDataReader) await cmd.ExecuteReaderAsync();
我被迫添加了一个意外的演员阵容(现在我明白为什么了)
我将把API包装在一个任务中。运行,因为我无法阻止我的UI
请参见下面的屏幕截图,将鼠标放在OpenAsync
上
从
这是Open()的异步版本。提供程序应使用适当的实现覆盖
默认实现调用同步Open()调用并返回已完成的任务
我个人的观点是,默认实现做了错误/误导的事情,我宁愿抛出一个异常“not implemented”(未实现)。ODP.NET不实现任何Async
-变量方法。基类具有调用非异步变量并使用Task.FromResult
(或使用缓存的Task
实例)包装结果的方法的实现。这些方法不在类型上声明。使用BindingFlags.DeclaredOnly
的基本反射不会检索这些方法。此外,ILSpy@Guilio一个常见的问题是,并非所有ADO.NET提供程序都以真正异步的方式实现所有API,这意味着它正在退回到异步而不是同步;在不知道确切版本并在本地拥有它的情况下,很难说某个特定的提供者是否这样做——老实说,要真正知道您需要查看程序集的IL。但是,是的,它已经发生了很多次times@Giulio使用Task.Run并不能改善异步而不是同步,并且会导致池耗尽,因此:no@Giulio我在讲一般情况;我没有检查ADO.NET的当前源代码,因为它已经将我们绑定到实现细节和特定版本中,但要澄清我的意思:不需要重写公共方法来提供API;在不更改/重写公共API的情况下重写具有足够效果的受保护方法并不少见。如果它在本例中不起作用,除了“在本例中”之外,它是有趣的,但不是确定的
OracleDataReader DR = (OracleDataReader) await cmd.ExecuteReaderAsync();