c# – Oracle托管驱动程序可以正常使用异步/等待吗?

前端之家收集整理的这篇文章主要介绍了c# – Oracle托管驱动程序可以正常使用异步/等待吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用异步/等待.NET功能进行Oracle查询.结果集相当大,大概需要5-10秒才能回来. Window_Loaded挂起了UI线程,本质上我想使用async / wait在后台执行查询,然后用结果更新dataview.

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

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:

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 Managed库同步地实现了Async方法(仅符合接口).

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();
}

解决方法

不,被管理的驱动程序不支持异步/等待.

您可以调用这些方法,因为它们必须被实现以符合接口定义,但代码实际上是同步的.你可以使用Task.Run,​​如果你想,但你不能同时有两个电话(Oracle会威胁他们同步).

原文链接:https://www.f2er.com/csharp/93615.html

猜你在找的C#相关文章