• 在SQL Server数据库上执行异步操作



    问题 

    有时候我们需要在SQL Server数据库上执行异步操作,即在后台任务中执行该操作,主程序则可以执行其它操作。

    解决方案

    使用SqlCommand类的BeginExecuteNonQuery、BeginExecuteReader或BeginExecuteXmlReader方法开始执行一个后台数据库操作。这些方法都会返回一个System.IAsyncResult对象,我们可以用它来获取操作的状态或使用同步线程等待该操作完成。使用IAsyncResult对象及SqlCommand相应的EndExecuteNonQuery、EndExecuteReader或EndExecuteXmlReader方法来获取操作的结果。

    注意:只有SqlCommand类支持这里所将的异步操作,与其等价的Oracle、OleDb等Data Provider的Command类没有提供这种功能。

    原理

    通常我们都需要执行同步的数据库操作,即调用代码会一直等待这些操作完成。这是因为我们通常都会用到数据库操作的结果。但有些时候,异步数据库操作也很有用。

    注意:要对一个SqlConnection连接执行异步操作,需要在其连接字符串中添加如下属性:Asynchronous Processing=true

    BeginExecuteNonQuery、BeginExecuteReader以及BeginExecuteXmlReader的参数可以跟其相应的同步操作方法ExecuteNonQuery、ExecuteReader、ExecuteXmlReader相同,同时它们还提供了重载方法接受两个额外的参数以支持异步操作:

    1. 一个System.AsyncCallBack类型的委托,操作完成后会调用委托指向的方法。如果该委托为null,那就要使用另一种机制来判断异步操作何时完成了;
    2. 一个object对象引用,运行时通过它与异步操作建立联系。异步操作不能访问这个对象,但我们的代码却可以在操作完成时访问它,这样就可以将异步操作与有用的状态信息联系在一起。

    当心: 在异步操作执行过程中,必须确保我们使用的对象不能被不经意地释放掉。尤其要注意SqlConnection和SqlCommand对象。

    示例代码

    代码中使用的数据库是Northwind,演示了上述技术的基本用法。

    class Program
    {
        
    public static void CallbackHandler(IAsyncResult result)
        {
            
    using (SqlCommand cmd = result.AsyncState as SqlCommand)
            {
                
    using (SqlDataReader reader = cmd.EndExecuteReader(result))
                {
                    
    lock (Console.Out)
                    {
                        Console.WriteLine(
    "Price of the The Most Expensive Products:");

                        
    while (reader.Read())
                        {
                            Console.WriteLine(
    "  {0} = {1}", reader["TenMostExpensiveProducts"], reader["UnitPrice"]);
                        }
                    }
                }
            }
        }

        
    static void Main(string[] args)
        {
            
    using (SqlConnection conn = new SqlConnection())
            {
                conn.ConnectionString 
    = @"server=(local);database=Northwind;uid=sa;Asynchronous Processing=true";
                SqlCommand cmd 
    = conn.CreateCommand();
                cmd.CommandType 
    = CommandType.StoredProcedure;
                cmd.CommandText 
    = "Ten Most Expensive Products";

                conn.Open();
                cmd.BeginExecuteReader(CallbackHandler, cmd);

                
    for (int count = 0; count < 10; count++)
                {
                    
    lock (Console.Out)
                    {
                        Console.WriteLine(
    "{0} : Continue processing", DateTime.Now.ToString("HH:mm:ss.ffff"));
                    }
                    Thread.Sleep(
    400);
                }
            }

            Console.WriteLine();
            Console.ReadLine();
        }
    }




    参考:
    Visual C# 2005 Recipes A Problem-Solution Approach -- Allen Jones, Matthew MacDonald, Rakesh Rajan.

    作者:Anders Cui
    出处:http://anderslly.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    8月15日
    【k8s】创建 tls 类型 Secret
    使用 openssl 生成 CA 证书
    【k8s】跨 Namespace 使用 Ingress
    Windows 和 Centos 导入 CA 证书
    使用 openssl 生成服务器证书
    【k8s】nginx ingress 配置 https
    【k8s】通过 https 访问 dashboard
    1012day人口普查系统
    8.3日志
  • 原文地址:https://www.cnblogs.com/anderslly/p/PerformAsynchronousDatabaseOperations.html
Copyright © 2020-2023  润新知