I am trying to make an asynchronous call to Oracle, but it gets executed synchronously. Please look at below code and tell me what I am doing wrong.
(I've installed ODAC (ODTwithODAC1120320_32bit.zip) and use the Oracle.DataAccess.dll assembly for my calls to Oracle. Before I used the deprecated System.Data.OracleClient with the same result.)
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();
}
}
}
It takes some minutes for the dbms to get the count. What I expect is this: ExecuteScalarAsync gets called and it gives Oracle a call. Immediately after the BEFORE time is written to label1. Then I wait for the Oracle query to finish and take its result. Then the AFTER time is written to label1. So BEFORE and AFTER should be different. However, they are always the same time (i.e. the time when the query returned its result). Why is that?
I also tried
CancellationToken cancellationToken = new CancellationToken();
Task<Object> result = command.ExecuteScalarAsync(cancellationToken);
and it didn't change anything. (What is this supposed to do anyhow? Would I not simply call command.Cancel();
instead of using a CancellationToken?)
My system: Windows 8 Pro 64bit, Visual Studio Express 2013, Oracle Client 11g (32bit): OCI 11.2.0.01
As far as I know, Oracle's provider still doesn't implement the asynchronous methods. This was asked previously and I can't find anything newer in Oracle's OTN or the discussion forums.
As the answer to the previous question says, the default implementation of the Async
methods is to call the synchronous counterparts rather than run them wrapped in Tasks (which could actually result in worse performance actually).