使用 ExecuteNonQueryAsync 并报告进度

2024-02-08

我以为我正在尝试做一些非常简单的事情。我只想在屏幕上报告一个运行数字,以便用户知道我正在执行的 SQL 存储过程正在工作,并且他们不会不耐烦并开始单击按钮。

问题是我无法弄清楚如何实际调用 ExecutNonQueryAsync 命令的进度报告器。它陷入我的报告循环中并且从不执​​行该命令,但是如果我将它放在异步命令之后,它将被执行并且结果永远不会不等于零。

任何想法、评论、想法将不胜感激。太感谢了!

        int i = 0;
        lblProcessing.Text = "Transactions " + i.ToString();
        int result = 0;
        while (result==0)
        {
            i++;
            if (i % 500 == 0)
            {
                lblProcessing.Text = "Transactions " + i.ToString();
                lblProcessing.Refresh();
            }

        }
        //  Yes - I know - the code never gets here - that is the problem! 
        result = await cmd.ExecuteNonQueryAsync();

最简单的方法是使用第二个连接来监视进度并报告进度。这是一个可以帮助您入门的小示例:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Samples.SqlServer
{
    public class SessionStats
    {
        public long Reads { get; set; }
        public long Writes { get; set; }
        public long CpuTime { get; set; }
        public long RowCount { get; set; }
        public long WaitTime { get; set; }
        public string LastWaitType { get; set; }
        public string Status { get; set; }

        public override string ToString()
        {
            return $"Reads {Reads}, Writes {Writes}, CPU {CpuTime}, RowCount {RowCount}, WaitTime {WaitTime}, LastWaitType {LastWaitType}, Status {Status}";
        }
    }
    public class SqlCommandWithProgress
    {


        public static async Task ExecuteNonQuery(string ConnectionString, string Query, Action<SessionStats> OnProgress)
        {
            using (var rdr = await ExecuteReader(ConnectionString, Query, OnProgress))
            {
                rdr.Dispose();
            }
        }

        public static async Task<DataTable> ExecuteDataTable(string ConnectionString, string Query, Action<SessionStats> OnProgress)
        {
            using (var rdr = await ExecuteReader(ConnectionString, Query, OnProgress))
            {
                var dt = new DataTable();

                dt.Load(rdr);
                return dt;
            }
        }


        public static async Task<SqlDataReader> ExecuteReader(string ConnectionString, string Query, Action<SessionStats> OnProgress)
        {
            var mainCon = new SqlConnection(ConnectionString);
            using (var monitorCon = new SqlConnection(ConnectionString))
            {
                mainCon.Open();
                monitorCon.Open();



                var cmd = new SqlCommand("select @@spid session_id", mainCon);
                var spid = Convert.ToInt32(cmd.ExecuteScalar());

                cmd = new SqlCommand(Query, mainCon);

                var monitorQuery = @"
select s.reads, s.writes, r.cpu_time, s.row_count, r.wait_time, r.last_wait_type, r.status
from sys.dm_exec_requests r
join sys.dm_exec_sessions s 
  on r.session_id = s.session_id
where r.session_id = @session_id";

                var monitorCmd = new SqlCommand(monitorQuery, monitorCon);
                monitorCmd.Parameters.Add(new SqlParameter("@session_id", spid));

                var queryTask = cmd.ExecuteReaderAsync( CommandBehavior.CloseConnection );

                var cols = new { reads = 0, writes = 1, cpu_time =2,row_count = 3, wait_time = 4, last_wait_type = 5, status = 6 };
                while (!queryTask.IsCompleted)
                {
                    var firstTask = await Task.WhenAny(queryTask, Task.Delay(1000));
                    if (firstTask == queryTask)
                    {
                        break;
                    }
                    using (var rdr = await monitorCmd.ExecuteReaderAsync())
                    {
                        await rdr.ReadAsync();
                        var result = new SessionStats()
                        {
                            Reads = Convert.ToInt64(rdr[cols.reads]),
                            Writes = Convert.ToInt64(rdr[cols.writes]),
                            RowCount = Convert.ToInt64(rdr[cols.row_count]),
                            CpuTime = Convert.ToInt64(rdr[cols.cpu_time]),
                            WaitTime = Convert.ToInt64(rdr[cols.wait_time]),
                            LastWaitType = Convert.ToString(rdr[cols.last_wait_type]),
                            Status = Convert.ToString(rdr[cols.status]),
                        };
                        OnProgress(result);

                    }

                }
                return queryTask.Result;


            }
        }
    }
}

你会这样称呼它:

    class Program
    {

        static void Main(string[] args)
        {
            Run().Wait();

        }
        static async Task Run()
        {
            var constr = "server=localhost;database=tempdb;integrated security=true";
            var sql = @"
set nocount on;
select newid() d
into #foo
from sys.objects, sys.objects o2, sys.columns 
order by newid();
select count(*) from #foo;
";

            using (var rdr = await SqlCommandWithProgress.ExecuteReader(constr, sql, s => Console.WriteLine(s)))
            {
                if (!rdr.IsClosed)
                {
                    while (rdr.Read())
                    {
                        Console.WriteLine("Row read");
                    }
                }
            }
            Console.WriteLine("Hit any key to exit.");
            Console.ReadKey();


        }
    }

哪个输出:

Reads 0, Writes 0, CPU 1061, RowCount 0, WaitTime 0, LastWaitType SOS_SCHEDULER_YIELD, Status running
Reads 0, Writes 0, CPU 2096, RowCount 0, WaitTime 0, LastWaitType SOS_SCHEDULER_YIELD, Status running
Reads 0, Writes 0, CPU 4553, RowCount 11043136, WaitTime 198, LastWaitType CXPACKET, Status suspended
Row read
Hit any key to exit.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ExecuteNonQueryAsync 并报告进度 的相关文章

随机推荐

  • 定期发送自动电子邮件

    我有带有 PostgreSQL 数据库的 Windows 服务器 我在数据库中存储了员工数据 包括合同到期日期 我想在到期日之前 30 天为每位员工发送一封自动电子邮件 每个员工都有一个电子邮件帐户 最好的方法是什么 我正在考虑执行以下操作
  • Sql Server 2014 - 更新到 Windows 10 且无法连接到本地服务器

    最近 我将 Windows 从 8 更新到 10 突然我的 SQL Server 2014 停止工作 当我打开 Management Studio 并尝试连接到服务器 本地 时 出现以下错误 你们中有人遇到过类似的问题吗 在更新 Windo
  • 解析c#类文件以获取属性和方法[重复]

    这个问题在这里已经有答案了 可能的重复 C 解析器 https stackoverflow com questions 81406 parser for c sharp 假设我有一个简单的类 例如 winforms 应用程序中的文本框控件内
  • 如何比较 viewDidLoad 和 viewDidAppear? [复制]

    这个问题在这里已经有答案了 我如何比较viewDidLoad and viewDidAppear 最好的办法是在视图控制器中实现这两种方法 该控制器加载带有子视图的视图 最简单的是来自 NIB 并在每个方法中放置一个断点 当应用程序在每个断
  • SQL Server 视图 - 错误的命名约定?

    DECLARE TableName AS VARCHAR 250 DECLARE SQL AS VARCHAR 500 DECLARE ViewCheck as CURSOR SET ViewCheck CURSOR FOR SELECT
  • 有没有办法从应用程序的 .ipa 存档中查看应用程序的 .entitlements 文件?

    我认为创建 ipa 时我的应用程序的 entitlements 文件存在问题 因此我想检查权利文件的捆绑 ID 在构建之前 我使用一个相当复杂的构建脚本来更改其中的一些内容 所以我想看看最终的产品是什么 我知道曾经有一个 Entitleme
  • 何时实施和扩展? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 什么时候应该implement or extend使用 有哪些现实世界的例子 它是否正确 实施似乎是强制类中存在某些方法并且这些方法函数调用格式
  • 检查委托是否为空

    我正在阅读 Essential C 3 0 一书 想知道这是否是检查委托是否为 null 的好方法 class Thermostat public delegate void TemperatureChangeHandler float n
  • cbind() 正在更改日期格式

    我正在尝试创建数据框的子集 当我这样做时 R 会切换日期列的格式 知道为什么或如何解决这个问题吗 gt head spyPr2 Date Open High Low Close Volume Adj Close 1 12 30 2011 1
  • Julia 中的方法链接

    I read https github com JuliaLang julia issues 5571 https github com JuliaLang julia issues 5571这让我觉得我可以因为一些评论而打破这样的界限 a
  • 无法在 systemd 203/EXEC 中将 Gunicorn 作为服务运行

    我正在尝试使用 Gunicorn WSGI Nginx 部署 FlaskApp 我已经尝试让它工作一段时间了 除了我一直遵循的数字海洋指南之外找不到任何东西 下面是我目前状态下的文件 我尝试了几种不同的调整mywebapp service文
  • 如何在 Chromium 浏览器中创建文本或将文本转换为音频?

    在尝试确定解决方案时如何在 chromium 上使用 Web Speech API https stackoverflow com questions 44013933 how to use web speech api at chromi
  • 对从方法调用的方法进行单元测试

    我有一个角度应用程序和一个在单击时触发的方法 在这个方法中 我将一个值传递给另一个私有方法 ts file public onViewItem item Results void const ids item data id this an
  • SQlite实体框架ADO.net提供程序错误1.0.92.0

    我试图了解 SQlite 和实体框架如何交互 我在 Visual Studio 2013 中创建了一个新的控制台项目 我安装了 SQlite 1 0 92 的 nuget 包 我创建一个新的空模型 edmx 并尝试从静态示例数据库 例如 N
  • opengl物体移动一段距离后振动

    我有一个在地形上移动的物体 第三人称摄像机跟随它 当我将它向不同方向移动一段距离后 即使它没有移动并且摄像机围绕它旋转 它也开始摇晃或振动 这就是移动对象的代码 double delta engine getDeltaTime GLfloa
  • Eclipse 无法启动 (Ubuntu):JVM 终止。退出代码=2

    我安装 ubuntu 14 04 LTS 64位 之后安装 Eclipse Luno Standard for 64bit 安装 Jdk 并使用以下链接按照设置 jdk 的所有步骤进行操作 http www wikihow com Inst
  • 使用 MOXy 和 XPath,是否可以解组两个属性列表?

    请注意 这不是我问的另一个问题的重复 使用 MOXy 和 XPath 是否可以解组属性列表 https stackoverflow com questions 6907225 with moxy and xpath is it possib
  • tf.keras.losses 中“BinaryCrossentropy”和“binary_crossentropy”的区别?

    我正在使用 tf GradientTape 使用 TensorFlow 2 0 训练模型 但我发现该模型的准确性为95 如果我使用tf keras losses BinaryCrossentropy 但降级为75 如果我使用tf keras
  • cURL 错误 60:SSL 证书:无法获取本地颁发者证书

    我尝试使用 Stripe 发送 API 请求 但收到错误消息 cURL 错误 60 SSL 证书问题 无法获取本地颁发者证书 这是我正在运行的代码 public function chargeStripe stripe new Stripe
  • 使用 ExecuteNonQueryAsync 并报告进度

    我以为我正在尝试做一些非常简单的事情 我只想在屏幕上报告一个运行数字 以便用户知道我正在执行的 SQL 存储过程正在工作 并且他们不会不耐烦并开始单击按钮 问题是我无法弄清楚如何实际调用 ExecutNonQueryAsync 命令的进度报