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

查看:34
本文介绍了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();
}


我试过了,它仍然阻塞用户界面:


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天全站免登陆