Oracle托管驱动程序可以正确使用async/await吗? [英] Can the Oracle managed driver use async/await properly?

查看:42
本文介绍了Oracle托管驱动程序可以正确使用async/await吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用async/await .NET功能进行Oracle查询.结果集非常大,大约需要5到10秒才能回来. Window_Loaded 挂在UI线程上,本质上我想使用async/wait在后台进行查询,然后使用结果更新数据视图.

I was trying to make an Oracle query with the async/await .NET feature. The result set is pretty large and takes about 5-10 seconds to come back. The Window_Loaded is hanging the UI thread, essentially I wanted to use async/wait to do the query in the background and then update a dataview with the result.

那么这是Oracle驱动程序问题还是代码错误?例如.是同步执行而不是异步执行?我正在使用最新的 Oracle.ManagedDataAccess ,可以从Oracle网站获取.

So is this an Oracle driver issue or a code error? E.g. is something here being done synchronously instead of asynchronously? I'm using the latest Oracle.ManagedDataAccess I could get from Oracle's web-site.

async Task<DataTable> AccessOracleAsync()
{
    DataTable dt;
    using(OracleConnection conn = new OracleConnection(ConfigurationManager
        .ConnectionStrings["connStr"].ConnectionString))
    using (OracleCommand cmd = new OracleCommand(@"SELECT * FROM myTbl", conn))
    {
        await conn.OpenAsync();
        using (var reader = await cmd.ExecuteReaderAsync())
        {
            dt = new DataTable();
            dt.Load(reader);                        
        }
    }
    return dt;
}

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    await AccessOracleAsync();
}


我尝试了此操作,但它仍然阻止了UI:


I tried this, and it is still blocking the UI:

async Task<DataView> AccessOracleAsync()
{
    DataTable dt;
    using (OracleConnection conn = new OracleConnection(ConfigurationManager
        .ConnectionStrings["connStr"].ConnectionString))
    using (OracleCommand cmd = new OracleCommand(@"SELECT * FROM myTbl", conn))
    {
        await conn.OpenAsync().ConfigureAwait(false);
        using (DbDataReader reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
        {
            dt = new DataTable();
            await Task.Run(() => dt.Load(reader)).ConfigureAwait(false);
        }
    }
    return dt.AsDataView();
}

private async void Window_Loaded(object sender, RoutedEventArgs e)
{
    Data1.ItemsSource = await AccessOracleAsync();
}


因此,最后,我将方法更改为类似的方法,以使其不会阻塞.看来我有一个正确的主意,只是Oracle托管库同步实现了Async方法(仅遵从该接口).


So in the end, I changed the method to something like this to make it not block. It appears I had the right idea, just that the Oracle managed library implemented the Async methods synchronously (only to comply with the interface).

private async Task<DataView> AccessOracleAsync()
{
    DataTable dt = new DataTable();
    using (OracleConnection conn = new OracleConnection(ConfigurationManager
        .ConnectionStrings["connStr"].ConnectionString))
    using (OracleCommand cmd = new OracleCommand(@"SELECT * myTbl", conn))
    {
        await Task.Run(() =>
        {
            conn.Open();
            using (DbDataReader reader = cmd.ExecuteReader())
            {
                dt.Load(reader);
            }
        }).ConfigureAwait(false);
    }
    return dt.AsDataView();
}

推荐答案

否.托管驱动程序不支持 async / await .

No. The managed driver does not support async / await.

您可以调用这些方法,因为必须实现它们以符合接口定义,但是代码实际上是同步的.您可以根据需要使用 Task.Run ,但不能同时进行两个调用(Oracle将威胁它们同步).

You can call those methods, since they must be implemented to comply with the interface definition, but the code is actually synchronous. You can use Task.Run if you want to, but you can't have two calls at the same time (Oracle will threat them synchronous).

这篇关于Oracle托管驱动程序可以正确使用async/await吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆