Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Oracle客户端与基于任务的异步模式(异步/等待)_C#_.net_Oracle_Task Parallel Library_Async Await - Fatal编程技术网

C# Oracle客户端与基于任务的异步模式(异步/等待)

C# Oracle客户端与基于任务的异步模式(异步/等待),c#,.net,oracle,task-parallel-library,async-await,C#,.net,Oracle,Task Parallel Library,Async Await,我想编写一系列方法,以异步/等待方式查询Oracle数据库。由于ODP.NET似乎既不支持可等待的*异步方法,也不支持Begin/INTEROPERATIONNAME对,因此我必须手动实现哪些选项 到目前为止,我看到的所有I/O密集型异步方法示例都只调用.NET库中的其他异步方法,但没有说明如何在内部完成上下文切换。文档中说,在这些情况下,没有使用单独的线程,而且多线程开销显然只适用于CPU密集型操作。所以我想使用Task.Run()不是一个选项,或者我错了吗?您可以始终将Task.Factor

我想编写一系列方法,以异步/等待方式查询Oracle数据库。由于ODP.NET似乎既不支持可等待的*异步方法,也不支持Begin/INTEROPERATIONNAME对,因此我必须手动实现哪些选项


到目前为止,我看到的所有I/O密集型异步方法示例都只调用.NET库中的其他异步方法,但没有说明如何在内部完成上下文切换。文档中说,在这些情况下,没有使用单独的线程,而且多线程开销显然只适用于CPU密集型操作。所以我想使用Task.Run()不是一个选项,或者我错了吗?

您可以始终将Task.Factory.StartNewTaskCreationOptions.LongRunning一起使用,这样.NET将创建一个新线程,而不是使用线程池线程。下面是可以应用于操作的手动异步代码

private static void ManualAsyncOperation()
        {

            Task<string> task = Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Accessing database .....");
                    //Mimic the DB operation 
                    Thread.Sleep(1000);

                    return "Hello wolrd";
                },TaskCreationOptions.LongRunning);

            var awaiter =task.GetAwaiter();
            awaiter.OnCompleted(() =>
                {
                    try
                    {
                        var result = awaiter.GetResult();

                        Console.WriteLine("Result: {0}", result);
                    }
                    catch (Exception exception)
                    {

                        Console.WriteLine("Exception: {0}",exception);
                    }
                });
            Console.WriteLine("Continuing on the main thread and waiting for the result ....");
            Console.WriteLine();

            Console.ReadLine();

        }
private static void ManualAsyncOperation()
{
Task Task=Task.Factory.StartNew(()=>
{
Console.WriteLine(“访问数据库…”);
//模拟DB操作
睡眠(1000);
返回“你好,沃尔德”;
},TaskCreationOptions.LongRunning);
var awaiter=task.GetAwaiter();
等待者。未完成(()=>
{
尝试
{
var result=waiter.GetResult();
WriteLine(“结果:{0}”,Result);
}
捕获(异常)
{
WriteLine(“异常:{0}”,异常);
}
});
WriteLine(“在主线程上继续并等待结果…”);
Console.WriteLine();
Console.ReadLine();
}
我在用这个

public static class TaskHelper
{
    public async static Task<T> AsAsync<T>(Func<T> function, TaskCreationOptions taskCreationOptions = TaskCreationOptions.None)
    {
        return await Task.Factory.StartNew(function, taskCreationOptions);
    }

    public async static Task AsAsync(Action action, TaskCreationOptions taskCreationOptions = TaskCreationOptions.None)
    {
        await Task.Factory.StartNew(action, taskCreationOptions);
    }
}
公共静态类TaskHelper
{
公共异步静态任务AsAsync(Func函数,TaskCreationOptions TaskCreationOptions=TaskCreationOptions.None)
{
返回wait Task.Factory.StartNew(函数、任务创建选项);
}
公共异步静态任务AsAsAsync(操作操作,TaskCreationOptions TaskCreationOptions=TaskCreationOptions.None)
{
等待Task.Factory.StartNew(操作、taskCreationOptions);
}
}

任何同步函数都可以是异步的,您可以等待它。

只要我知道Oracle ODP是异步库的同步包装器。我发现这篇文章时也在想同样的问题:为Oracle ODP调用引入异步模式会提高性能吗?(我正在IIS网络TCP上使用WCF)


但是,正如前面所说的,只要引入异步模式创建了一个新任务,并且调用线程已经来自线程池,就不会有任何改进,这将只是一种开销。

ODP.NET是否有任何可以调整的异步模式?您可能想了解是否使用ODP.NET以外的其他选项(商业ADO.NET提供程序)?@metalheart好的,那么唯一的选项是使用连接池并构建任务,以便他们从该池请求所需的连接。。。这样,您应该能够使用
任务。运行
。。。虽然性能不如“真正的异步”,但它应该会给您带来一些好处…@Jon:ODP.NET中目前绝对没有异步执行支持。@metalheart我明白。。。正如我所说的:您不会获得与真正的异步实现相同的效果,但它会比“纯同步”更好。。。据我所知,Oracle的唯一ADO.NET提供程序具有真正的异步支持,它们是商业性的,您已经排除了这一点。。。所以没有什么可以帮你的,对不起!我很好奇是否可以不使用线程实现异步行为。。。当以这种方式调用许多DB操作时,我的解决方案可能无法很好地扩展。为什么要使用GetAwaiter()而不是普通的延续(或
await
)?@ReedCopsey对于这个特定的问题,作者问道“既然ODP.NET似乎既不支持waitiable*异步方法,也不支持Begin/EndOperationName对,那么我需要哪些选项来手动实现它?”,所以我使用了getwaitier()。抱歉,响应延迟。@对于Annguyen,您应该在从task.Factory.StartNew创建的任务上使用ContinueWith-在这种情况下,没有理由获取等待者…创建延续是一个奇怪的选择。这会降低吞吐量。不适合服务器端使用。当然,如果不使用异步操作,您必须避免使用异步操作需要它们是异步的。但是如果你想要UI或IIS的非阻塞行为,你必须这样做。但是就像我所说的,你必须这么做,我在这里需要异步操作,还是不需要。在IIS中,你不需要非阻塞行为。对于UI,这很有用。正如我所知,通过使用异步,IIS可以同时响应更多请求。它不能。IIS请求使用标准线程池。返回一个线程,然后立即拉出另一个线程。IIS和ASP.NET对于请求的并行执行没有实际相关的限制(不容易提高)。