programing

Oracle 관리 드라이버는 비동기/대기 기능을 올바르게 사용할 수 있습니까?

muds 2023. 3. 2. 22:43
반응형

Oracle 관리 드라이버는 비동기/대기 기능을 올바르게 사용할 수 있습니까?

async/ait를 사용하여 Oracle 쿼리를 작성하려고 했습니다.NET 기능결과 세트가 꽤 크고 돌아오는 데 5-10초 정도 걸립니다.Window_LoadedUI 스레드를 행하고 있습니다.기본적으로 비동기/대기 기능을 사용하여 백그라운드에서 쿼리를 수행한 후 결과로 데이터 뷰를 업데이트하려고 했습니다.

Oracle 드라이버 문제입니까, 코드 오류입니까?예를 들어, 여기서 뭔가 비동기적이지 않고 동기적으로 이루어지고 있습니까?최신 버전을 사용하고 있습니다.Oracle.ManagedDataAccessOracle 웹사이트에서 얻을 수 있습니다.

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 관리 라이브러리가 비동기 메서드를 동기화(인터페이스에 준거하기 위해서만)한 것이 올바른 생각이었던 것 같습니다.

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.

인터페이스 정의에 준거하기 위해서 실장할 필요가 있기 때문에, 이러한 메서드를 호출할 수 있습니다만, 실제로는 코드가 동기하고 있습니다.사용할 수 있습니다.Task.Run동시에 2개의 콜을 가질 수 없습니다(Oracle은 동기식으로 위협합니다).

(오라클 관리 드라이버가 비동기 기능을 올바르게 지원하도록 하기 위한 "솔루션"인 것 같기 때문에 답변으로 남겨둡니다.)

Oracle 사이트에서 오래된 스레드(2010년 이후)를 발견했는데, Oracle PM은 이 스레드를 지원하지 않는다고 합니다.투표(Oracle 계정 필요)를 통해 해당 기능을 포함할 수 있습니다.5년이 지난 지금 안타깝게도 60표밖에 얻지 못했다.

ODP의 23C 릴리즈에 마일스톤을 설정하는 Github 문제가 있습니다.NET. Oracle Cloud World 2022 중 비동기 구현 중단도 발표되었습니다.

언급URL : https://stackoverflow.com/questions/29016698/can-the-oracle-managed-driver-use-async-await-properly

반응형