Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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# 使用ADO.NET对Oracle DB的异步调用_C#_Asp.net_Webforms_Ado.net_Async Await - Fatal编程技术网

C# 使用ADO.NET对Oracle DB的异步调用

C# 使用ADO.NET对Oracle DB的异步调用,c#,asp.net,webforms,ado.net,async-await,C#,Asp.net,Webforms,Ado.net,Async Await,我正在尝试使用.NETFramework4.5中提供的异步和等待功能执行多个数据库调用。这是我第一次实现此功能 如果每个查询耗时7秒,则通常需要35秒(5个查询*7秒)。在下面的实现中,我希望它能在7-9秒内获取并填充asp页面中的控件。然而,它仍然需要35秒,证明了我的同步行为 有人能帮助我在下面的异步实现中哪里出了问题吗 我很感激你的任何意见,从几天以来我一直在为这件事绞尽脑汁 protected void Page_Load(object sender, System.EventA

我正在尝试使用.NETFramework4.5中提供的异步和等待功能执行多个数据库调用。这是我第一次实现此功能

如果每个查询耗时7秒,则通常需要35秒(5个查询*7秒)。在下面的实现中,我希望它能在7-9秒内获取并填充asp页面中的控件。然而,它仍然需要35秒,证明了我的同步行为

有人能帮助我在下面的异步实现中哪里出了问题吗

我很感激你的任何意见,从几天以来我一直在为这件事绞尽脑汁

    protected void Page_Load(object sender, System.EventArgs e)
    {
        RegisterAsyncTask(new PageAsyncTask(FillControlsAsync));
    }

    public async Task FillControlsAsync()
    {
         Task[] tasks = new Task[]{
         PopulateControlTask(query1, "controlID1"),
         PopulateControlTask(query2, "controlID2"),
         PopulateControlTask(query3, "controlID3"),
         PopulateControlTask(query4, "controlID4"),
         PopulateControlTask(query5, "controlID5")
        });

        await Task.WhenAll(tasks);
    }
    public async Task PopulateControlTask(string query, string control)
    {
       await Task.Run(() =>
           {
               DataSet ds;
               OracleCommand cmd;
               OracleDataAdapter da;
               try
               {
                   if (!Page.IsPostBack)
                   {
                       cmd = new OracleCommand(query, cn);
                       da = new OracleDataAdapter(cmd);
                       ds = new DataSet();
                       da.Fill(ds);
                       switch (control)
                       {
                           case "controlID1":
                                //some custom code for control 1
                                // like attaching the datasource to control.
                               break;
                           case "controlID2":
                               //some custom code for control 2
                               break;
                            case "controlID2":
                            //some custom code for control 3
                            break;
                            case "controlID3":
                            //some custom code for control 4
                            break;
                            case "controlID4":
                            //some custom code for control 5
                            break;
                    }
                }
            }
            catch(Exception e)
            {
                 //some error handling here
            }
        });
    }

async
await
用于异步代码。通常,如果您有一个可伸缩的数据库,您可以使db调用异步,从而扩展服务器。请注意,ASP.NET上的
async
的主要好处是可伸缩性,而不是响应时间

然而,正如其他人所指出的,Oracle不支持异步代码

但这并不重要,因为您发布的代码一开始就不是异步的!这就是我所说的“伪异步”,因为它只是使用
Task.Run
将同步工作推到后台线程,而不是使用自然异步API。(但如前所述,在本例中(即Oracle),您没有任何可使用的自然异步API)

因此,最终得到的是并行性,而不是异步性。特别是,代码将自己扩展到5个线程池线程上以完成其工作

现在,您需要做的第一件事是问问自己,您是否真的想要服务器上的并行性。您的请求将占用5个线程,而不是1(或0)。这会极大地影响web服务器的可伸缩性(以一种不好的方式)。此外,还要考虑后端的功能。如果是一台服务器,而这些查询都是在单个硬盘驱动器上访问单个数据库,那么将其中的5个并行化是否真的会产生任何好处,或者,由于磁盘争用,如果不是更糟的话,它是否真的会同样糟糕?(您应该能够快速启动一个控制台应用程序,测试您的数据库在空闲和负载下如何响应串行和并行请求)

我发现,绝大多数情况下,答案是“不,我不想让我的整个数据库服务器屈服于这一请求”——换句话说,避免服务器上的并行性

但是,如果您权衡了各种选择,认为是的,您的选择是ASP.NET上适合并行性的罕见案例之一,那么您应该问您在这里发布的问题:为什么这些选择是按顺序运行的,而不是同时运行的?(旁注:这里是顺序vs并发,而不是同步vs异步)

回答:我不知道

但我有一个猜测:如果数据库连接(
cn
在您的代码片段中)是共享的,那么很可能db连接本身一次只限于一个查询。其他数据库连接系统也有类似的限制。我要做的第一件事是为每个查询提供自己的连接


也就是说,如果您想并行化web服务器。这是一个很大的“如果”

async
wait
用于异步代码。通常,如果您有一个可伸缩的数据库,您可以使db调用异步,从而扩展服务器。请注意,ASP.NET上的
async
的主要好处是可伸缩性,而不是响应时间

然而,正如其他人所指出的,Oracle不支持异步代码

但这并不重要,因为您发布的代码一开始就不是异步的!这就是我所说的“伪异步”,因为它只是使用
Task.Run
将同步工作推到后台线程,而不是使用自然异步API。(但如前所述,在本例中(即Oracle),您没有任何可使用的自然异步API)

因此,最终得到的是并行性,而不是异步性。特别是,代码将自己扩展到5个线程池线程上以完成其工作

现在,您需要做的第一件事是问问自己,您是否真的想要服务器上的并行性。您的请求将占用5个线程,而不是1(或0)。这会极大地影响web服务器的可伸缩性(以一种不好的方式)。此外,还要考虑后端的功能。如果是一台服务器,而这些查询都是在单个硬盘驱动器上访问单个数据库,那么将其中的5个并行化是否真的会产生任何好处,或者,由于磁盘争用,如果不是更糟的话,它是否真的会同样糟糕?(您应该能够快速启动一个控制台应用程序,测试您的数据库在空闲和负载下如何响应串行和并行请求)

我发现,绝大多数情况下,答案是“不,我不想让我的整个数据库服务器屈服于这一请求”——换句话说,避免服务器上的并行性

但是,如果您权衡了各种选择,认为是的,您的选择是ASP.NET上适合并行性的罕见案例之一,那么您应该问您在这里发布的问题:为什么这些选择是按顺序运行的,而不是同时运行的?(旁注:这里是顺序vs并发,而不是同步vs异步)

回答:我不知道

但我有一个猜测:如果数据库连接(
cn
在您的代码片段中)是共享的,那么很可能db连接本身一次只限于一个查询。其他数据库连接系统也有类似的限制。我要做的第一件事是为每个查询提供自己的连接


也就是说,如果您想并行化web服务器。哪一个是大的“如果”

你真的有一个空的挡块吗?这是一种反模式