使用Oracle.DataAccess(ODAC)在C#中进行异步调用

本文关键字:异步 调用 DataAccess Oracle ODAC 使用 | 更新日期: 2023-09-27 18:29:02

我试图对Oracle进行异步调用,但它是同步执行的。请看下面的代码,告诉我我做错了什么。

(我已经安装了ODAC(ODTwithODAC1120320_32bit.zip),并使用Oracle.DataAccess.dll程序集调用Oracle。在我使用不推荐使用的System.Data.OracleClient并获得相同结果之前。)

using System;
...
using System.Threading;
using System.Threading.Tasks;
using Oracle.DataAccess.Client;
namespace OracleTest
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
    async private void button1_Click(object sender, EventArgs e)
    {
      OracleConnection connection = new OracleConnection("User Id=myuser;Password=mypwd;Data Source=mydb");
      connection.Open();  
      OracleCommand command = new OracleCommand("select count(col) from bigtable", connection);
      Task<Object> result = command.ExecuteScalarAsync();
      label1.Text = "BEFORE" + DateTime.Now.ToLocalTime() + " - ";
      label1.Text += await result;
      label1.Text += " - AFTER " + DateTime.Now.ToLocalTime();
      connection.Close(); 
      connection.Dispose(); 
    }
  }
}

dbms需要几分钟才能得到计数。我所期望的是:调用ExecuteScalarAsync,它给Oracle一个调用。BEFORE时间写入标签1之后。然后我等待Oracle查询完成并获取结果。然后将AFTER时间写入标签1。所以BEFORE和AFTER应该是不同的。但是,它们总是相同的时间(即查询返回结果的时间)。为什么?

我也试过

  CancellationToken cancellationToken = new CancellationToken();
  Task<Object> result = command.ExecuteScalarAsync(cancellationToken);

它并没有改变任何事情。(无论如何,这应该做什么?我不简单地调用command.Cancel();而不是使用CancellationToken吗?)

我的系统:Windows 8 Pro 64位,Visual Studio Express 2013,Oracle Client 11g(32位):OCI 11.2.0.01

使用Oracle.DataAccess(ODAC)在C#中进行异步调用

据我所知,Oracle的提供程序仍然没有实现异步方法。这是以前问过的,我在Oracle的OTN或论坛上找不到任何更新的内容。

正如前面问题的答案所说,Async方法的默认实现是调用同步对应方,而不是在任务中运行它们(这实际上可能会导致更差的性能)。

如果您查看ExecuteScalarAsync的文档,它清楚地表明它"实现异步版本的ExecuteScalar,但同步返回一个Task,阻塞调用线程。。因此,它似乎正按照它所说的做(阻塞调用线程)。

要利用ExecuteScalarAsync,您需要执行类似的操作

using (object obj = await command.ExecuteScalarAsync())
{
   //....
}

祝你好运。