我想写一堆以异步/等待方式查询Oracle数据库的方法。由于 ODP.NET 似乎既不支持可等待的 *Async 方法也不支持 Begin/EndOperationName 对,我必须手动实现哪些选项?
到目前为止,我看到的所有 I/O 密集型异步方法的示例都只调用了 .NET 库中的其他异步方法,但没有说明在内部完成上下文切换的方式。文档说,在这些情况下,没有使用单独的线程,而且多线程开销显然只对 CPU 密集型操作有价值。所以我想使用 Task.Run() 不是一个选项,还是我错了?
我想写一堆以异步/等待方式查询Oracle数据库的方法。由于 ODP.NET 似乎既不支持可等待的 *Async 方法也不支持 Begin/EndOperationName 对,我必须手动实现哪些选项?
到目前为止,我看到的所有 I/O 密集型异步方法的示例都只调用了 .NET 库中的其他异步方法,但没有说明在内部完成上下文切换的方式。文档说,在这些情况下,没有使用单独的线程,而且多线程开销显然只对 CPU 密集型操作有价值。所以我想使用 Task.Run() 不是一个选项,还是我错了?
只要我知道 Oracle ODP 是异步库的同步包装器。我发现这篇文章只是想知道同样的问题:为 Oracle ODP 调用引入异步模式会提高性能吗?(我在 IIS NET TCP 上使用 WCF)。
但是,正如上面所说,只要引入了异步模式,创建了一个新的Task,并且调用线程已经从线程池中,就无法进行任何改进,这只是一个开销。
我正在使用这个
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);
}
}
任何同步函数都可以异步,你可以等待它。
您始终可以将Task.Factory.StartNew 与TaskCreationOptions.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();
}