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

问题描述

我试图让一个Oracle查询与异步/等待.NET功能。结果集是pretty的大,大约需要5-10秒回来。该Window_Loaded是挂在UI线程,基本上我想用异步/等待做后台查询,然后更新与结果的数据视图。

所以这是一个Oracle驱动程序问题或code错误?例如。东西在这里正在做同步,而不是异步?我使用的是最新的 Oracle.ManagedDataAccess 我能得到来自Oracle的网站。

 异步任务<数据表> AccessOracleAsync()
{
    数据表DT;
    使用(康涅狄格州的OracleConnection =新的OracleConnection(ConfigurationManager.ConnectionStrings [connStr。的ConnectionString))
    使用(CMD的OracleCommand =新的OracleCommand(@SELECT * FROM MYTBL,康涅狄格州))
    {
        等待conn.OpenAsync();
        使用(VAR读卡器=等待cmd.ExecuteReaderAsync())
        {
            DT =新的DataTable();
            dt.Load(读卡器);
        }
    }

    返回DT;
}

私人异步无效Window_Loaded(对象发件人,RoutedEventArgs E)
{
    等待AccessOracleAsync();
}
 


我想这一点,而且它仍然是死锁的用户界面:

 异步任务<数据视图> AccessOracleAsync()
{
        数据表DT;
        使用(康涅狄格州的OracleConnection =新的OracleConnection(ConfigurationManager.ConnectionStrings [connStr。的ConnectionString))
        使用(CMD的OracleCommand =新的OracleCommand(@SELECT * FROM MYTBL,康涅狄格州))
        {
            等待conn.OpenAsync()ConfigureAwait(假)。
            使用(DbDataReader读卡器=等待cmd.ExecuteReaderAsync()。ConfigureAwait(假))
            {
                DT =新的DataTable();
                等待Task.Run(()=> dt.Load(阅读器))。ConfigureAwait(假);
            }

        }
        返回dt.AsDataView();
}

私人异步无效Window_Loaded(对象发件人,RoutedEventArgs E)
{
    Data1.ItemsSource =等待AccessOracleAsync();
}
 


所以,最后,我改变了方法,这样的事情,使之不死锁。看来我是对的,只是在Oracle托管库实现了异步方法同步(仅限于符合接口)。

 专用异步任务<数据视图> AccessOracleAsync()
{
        数据表DT =新的DataTable();
        使用(康涅狄格州的OracleConnection =新的OracleConnection(ConfigurationManager.ConnectionStrings [connStr。的ConnectionString))
        使用(CMD的OracleCommand =新的OracleCommand(@SELECT * MYTBL,康涅狄格州))
        {
            等待Task.Run(()=>
                {
                    conn.Open();
                    使用(DbDataReader读卡器= cmd.ExecuteReader())
                    {
                        dt.Load(读卡器);
                    }
                })ConfigureAwait(假);

        }
        返回dt.AsDataView();
}
 

解决方案

没有。托管驱动程序不支持异步 / 等待

您可以调用这些方法,因为它们必须实施符合接口定义,但code其实是同步的。您可以使用 Task.Run 如果你想,但你不能在同一时间两个呼叫(Oracle将威胁他们的同步)。

I was trying to make an Oracle query with the async/wait .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.

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


So in the end, I changed the method to something like this to make it not deadlock. 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();
}
解决方案

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

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托管驱动程序使用异步/等是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 13:13
查看更多