C# 加速取消信号到Oracle

C# 加速取消信号到Oracle,c#,oracle,async-await,task-parallel-library,cancellation,C#,Oracle,Async Await,Task Parallel Library,Cancellation,当我使用CancellationToken方法取消我的任务时,它通常会在30秒左右被取消。时间取决于Oracle中的查询量,甚至可能需要1分钟 在不同的线程上使用任务调用任务。运行(在获取数据时执行一些UI加载动画) 若用户在运行时取消任务(关闭窗口),并在应用程序中启动一些新的Oracle任务,那个么事情就会变得一团糟——Oracle中突然出现了许多打开的会话。我想通过加速取消信号来避免这种情况 这是我的密码: //global static variable, defined whe

当我使用
CancellationToken
方法取消我的任务时,它通常会在30秒左右被取消。时间取决于Oracle中的查询量,甚至可能需要1分钟

在不同的线程上使用
任务调用任务。运行
(在获取数据时执行一些UI加载动画)

若用户在运行时取消任务(关闭窗口),并在应用程序中启动一些新的Oracle任务,那个么事情就会变得一团糟——Oracle中突然出现了许多打开的会话。我想通过加速取消信号来避免这种情况

这是我的密码:

    //global static variable, defined when window opens
    CancellationTokenSource cts= new  CancellationTokenSource(); 
    
    //CancellationToken get's cancelled when user leaves window
    private void OnCloseWindow(object target, ExecutedRoutedEventArgs e)
    {
         cts.Cancel(); 
    }
    
    public async Task<List<EmployeeModel>> Get_Employees(CancellationToken cts)
    {
      var data = new List<EmployeeModel>();
        
      try
      {
        using (OracleConnection con = new OracleConnection(conn_string))
        {
           con.OpenAsync(cts);
        
           OracleCommand cmd = new OacleCommand("Myschema.Procedure_1", con)
           {
             CommandType = CommandType.StoredProcedure
           };
           cmd.Parameters.Add("name_in", OracleDbType.Varchar2).Value = "John";
           cmd.Parameters.Add("surname_in", OracleDbType.Varchar2).Value = "Black";
                       
           using (cts.Register(() => cmd.Cancel()))
           {            
             using (OracleDataReader rdr = cmd.ExecuteReaderAsync(cts))
             {
               while (await rdr.ReadAsync(cts))
               {  
                 data.Add(new EmployeeModel()
                 {
                   NAME = rdr.IsDBNull(0) ? null : rdr.GetString(0),
                   SURNAME = rdr.IsDBNull(1) ? null : rdr.GetString(1)
                 });
               }
             }
           }
         }
      }
      return data;
      }
      catch (OperationCanceledException)
      {
        return null;
      }
      catch (Exception)
      {
        return null;
      }
   }
//全局静态变量,在窗口打开时定义
CancellationTokenSource cts=新的CancellationTokenSource();
//CancellationToken在用户离开窗口时被取消
私有void OnCloseWindow(对象目标,ExecutedRoutedEventTarget)
{
cts.Cancel();
}
公共异步任务获取\u员工(CancellationToken cts)
{
var data=新列表();
尝试
{
使用(OracleConnection con=新的OracleConnection(conn_字符串))
{
con.OpenAsync(cts);
OracleCommand cmd=新的OacleCommand(“Myschema.Procedure_1”,con)
{
CommandType=CommandType.StoredProcess
};
cmd.Parameters.Add(“name_in”,OracleDbType.Varchar2).Value=“John”;
cmd.Parameters.Add(“name_in”,OracleDbType.Varchar2).Value=“Black”;
使用(cts.Register(()=>cmd.Cancel())
{            
使用(OracleDataReader rdr=cmd.ExecuteReaderAsync(cts))
{
while(等待rdr.ReadAsync(cts))
{  
data.Add(新员工模型()
{
NAME=rdr.IsDBNull(0)?null:rdr.GetString(0),
姓氏=rdr.IsDBNull(1)?null:rdr.GetString(1)
});
}
}
}
}
}
返回数据;
}
捕获(操作取消异常)
{
返回null;
}
捕获(例外)
{
返回null;
}
}
我正在使用OracleManagedDataAccess.dll,版本4.122.19.1。我的解决方法是对连接字符串使用
Max pool size=3
的设置。至少在测试期间,在Oracle中一次生成的会话不会超过3个,但我不确定这是否正确


我还可以做些什么来加快取消Oracle的步伐吗?某种我不知道的机制?

问题是-Oracle没有正确实现异步API。事实上,它是同步的,所以这就是为什么您会在不应该发生死锁/超时的地方看到死锁/超时(所有那些接受cancellationtoken的奇特异步方法)。为了缓解问题,请自己检查取消令牌,并在每个周期呕吐。此外,您还可以在注册操作中关闭datareader。它将爆发出一系列错误,但我看不出有什么办法可以避免Oracle PM的愚蠢。另外,在stackoverflow()上。显然他们根本不关心异步/性能。@eocron,谢谢你的回答。所以,这意味着我不能实现适当的取消也与非托管驱动程序?我不确定,你可以尝试,但我怀疑它会有任何更好的所有编组混乱。迁移到其他数据库可能更好,这些数据库实际上支持用户,而不是放弃用户—ms sql、mysql等。在所有开发人员的问题中,最重要的是做艰难的决定,并向团队展示你的决定的优缺点,而不是含糊不清的“会更好”。所以,这也是你的错。您要么解决问题,要么解释为什么当前体系结构不允许您在合理的时间内解决问题。您可以为sql连接设计Thread.Abort,但如何降低应用程序环境完全崩溃的风险呢?我会说“你要么改变数据库,给Oracle一大笔钱来修复这个问题,要么干脆迁移到其他数据库”,写下所有的优点/缺点,让他们考虑一下。问题是-Oracle没有正确地实现异步API。事实上,它是同步的,所以这就是为什么您会在不应该发生死锁/超时的地方看到死锁/超时(所有那些接受cancellationtoken的奇特异步方法)。为了缓解问题,请自己检查取消令牌,并在每个周期呕吐。此外,您还可以在注册操作中关闭datareader。它将爆发出一系列错误,但我看不出有什么办法可以避免Oracle PM的愚蠢。另外,在stackoverflow()上。显然他们根本不关心异步/性能。@eocron,谢谢你的回答。所以,这意味着我不能实现适当的取消也与非托管驱动程序?我不确定,你可以尝试,但我怀疑它会有任何更好的所有编组混乱。迁移到其他数据库可能更好,这些数据库实际上支持用户,而不是放弃用户—ms sql、mysql等。在所有开发人员的问题中,最重要的是做艰难的决定,并向团队展示你的决定的优缺点,而不是含糊不清的“会更好”。所以,这也是你的错。您要么解决问题,要么解释为什么当前体系结构不允许您在合理的时间内解决问题。您可以为sql连接设计Thread.Abort,但如何降低应用程序环境完全崩溃的风险呢?我会说“你们要么改变数据库,付给甲骨文一大笔钱来修复这个问题,要么干脆迁移到其他数据库”,写下所有的优点/缺点,让他们考虑一下。