none
关于异步中的WaitHAndle.WaitAny RRS feed

  • 问题

  • 很多书上都写着再循环中使用WaitHAndle.WaitAny,遍历异步进程,如下:

     for (int Index = 0; Index < 2; Index++)
            {
                // We are only waiting for any of the two 
                // asynchronous process to finish running
                WHIndex = System.Threading.WaitHandle.WaitAny(WHandles);
    
                // The return value from the WaitAny method is
                // the array index of the Wait Handle that just 
                // finsihed running
                switch (WHIndex)
                {
                    case 0:
                        CustReader = CustCommand.EndExecuteReader(CustAsyncResult);
    
                        gvCustomers.DataSource = CustReader;
                        gvCustomers.DataBind();
                        break;
                    case 1:
                        OrdersReader =
                           OrdersCommand.EndExecuteReader(OrdersASyncResult);
    
                        gvOrders.DataSource = OrdersReader;
                        gvOrders.DataBind();
                        break;
                }
            }

    但是我发现根本就不行,总是报错,原因是每次返回的都是同一个索引,给我解答一下


    please verify my account

    2015年8月25日 14:58

答案

  • WHhandles是信号量,用于等待的。请问您如何使用的?

    另外,此处为什么用循环?我认为貌似没有必要。


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月26日 5:55
  • WHhandles是信号量,用于等待的,是什么意思?

    asp.net 4高级编程或者ado。net2.0技术内幕,都是这么用的,

    如下:waitAny(WaidHandles),这是一个静态方法,如果以数组的形式管理多个WaitHandle,就可以使用它。使用这个方法会等待所有的异步进程都结束,并且其WaitHandle位于传送给它的数组中。waitany()方法必须重复调用,为每个要处理的WaitHandle调用一次。

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Configuration" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            SqlConnection DBCon;
            SqlCommand OrdersCommand = new SqlCommand();
            SqlCommand CustCommand = new SqlCommand();
            SqlDataReader OrdersReader;
            SqlDataReader CustReader;
            IAsyncResult OrdersASyncResult;
            IAsyncResult CustAsyncResult;
    
            int WHIndex;
            System.Threading.WaitHandle[] WHandles = 
               new System.Threading.WaitHandle[2];
            System.Threading.WaitHandle OrdersWHandle;
            System.Threading.WaitHandle CustWHandle;
    
            DBCon = new SqlConnection();
            DBCon.ConnectionString =             
              ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;
    
            CustCommand.CommandText = 
               "SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste'";
    
            CustCommand.CommandType = CommandType.Text;
            CustCommand.Connection = DBCon;
    
            OrdersCommand.CommandText = 
                    "SELECT Customers.CompanyName, Customers.ContactName, " +
                    "Orders.OrderID, Orders.OrderDate, " +
                    "Orders.RequiredDate, Orders.ShippedDate " +
                    "FROM Orders, Customers " +
                    "WHERE Orders.CustomerID = Customers.CustomerID " +
                    "AND Customers.CompanyName = 'Alfreds Futterkiste' " +
                    "ORDER BY Customers.CompanyName, Customers.ContactName";
    
            OrdersCommand.CommandType = CommandType.Text;
            OrdersCommand.Connection = DBCon;
    
            // Opening the database connection
            DBCon.Open();
    
            // Retrieving customer information asynchronously
            CustAsyncResult = CustCommand.BeginExecuteReader();
    
            // Retrieving orders list asynchronously
            OrdersASyncResult = OrdersCommand.BeginExecuteReader();
    
            CustWHandle = CustAsyncResult.AsyncWaitHandle;
            OrdersWHandle = OrdersASyncResult.AsyncWaitHandle;
    
            // Filling Wait Handles array with the two wait handles we
            // are going to use in this code
            WHandles[0] = CustWHandle;
            WHandles[1] = OrdersWHandle;
    
            // Looping 2 times because there are 2 wait handles 
            // in the array
            for (int Index = 0; Index < 2; Index++ )
            {
                // We are only waiting for any of the two 
                // asynchronous process to finish running
                WHIndex = System.Threading.WaitHandle.WaitAny(WHandles);
    
                // The return value from the WaitAny method is
                // the array index of the Wait Handle that just 
                // finsihed running
                switch (WHIndex)
                {
                    case 0:
                        CustReader = CustCommand.EndExecuteReader(CustAsyncResult);
    
                        gvCustomers.DataSource = CustReader;
                        gvCustomers.DataBind();
                        break;
                    case 1:
                        OrdersReader = 
                           OrdersCommand.EndExecuteReader(OrdersASyncResult);
    
                        gvOrders.DataSource = OrdersReader;
                        gvOrders.DataBind();
                        break;
                }
            }
            // Closing connection
            DBCon.Close();
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title>The Wait Any Approach</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        <asp:GridView ID="gvCustomers" Width="100%" runat="server"></asp:GridView>
        <br /><br />
        <asp:GridView ID="gvOrders" Width="100%" AutoGenerateColumns="False"         
         runat="server">
           <Columns>
              <asp:BoundField HeaderText="Company Name" 
               DataField="CompanyName"></asp:BoundField>
              <asp:BoundField HeaderText="Contact Name" 
               DataField="ContactName"></asp:BoundField>
              <asp:BoundField HeaderText="Order Date" DataField="orderdate" 
               DataFormatString="{0:d}"></asp:BoundField>
              <asp:BoundField HeaderText="Required Date" DataField="requireddate" 
               DataFormatString="{0:d}"></asp:BoundField>
              <asp:BoundField HeaderText="Shipped Date" DataField="shippeddate" 
               DataFormatString="{0:d}"></asp:BoundField>
           </Columns>
        </asp:GridView>
        </div>
        </form>
    </body>
    </html>
    


    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月26日 10:48
  • 尝试直接移除For循环:

     protected void Page_Load(object sender, EventArgs e)
        {
            SqlConnection DBCon;
            SqlCommand OrdersCommand = new SqlCommand();
            SqlCommand CustCommand = new SqlCommand();
            SqlDataReader OrdersReader;
            SqlDataReader CustReader;
            IAsyncResult OrdersASyncResult;
            IAsyncResult CustAsyncResult;
    
            int WHIndex;
            System.Threading.WaitHandle[] WHandles = 
               new System.Threading.WaitHandle[2];
            System.Threading.WaitHandle OrdersWHandle;
            System.Threading.WaitHandle CustWHandle;
    
            DBCon = new SqlConnection();
            DBCon.ConnectionString =             
              ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;
    
            CustCommand.CommandText = 
               "SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste'";
    
            CustCommand.CommandType = CommandType.Text;
            CustCommand.Connection = DBCon;
    
            OrdersCommand.CommandText = 
                    "SELECT Customers.CompanyName, Customers.ContactName, " +
                    "Orders.OrderID, Orders.OrderDate, " +
                    "Orders.RequiredDate, Orders.ShippedDate " +
                    "FROM Orders, Customers " +
                    "WHERE Orders.CustomerID = Customers.CustomerID " +
                    "AND Customers.CompanyName = 'Alfreds Futterkiste' " +
                    "ORDER BY Customers.CompanyName, Customers.ContactName";
    
            OrdersCommand.CommandType = CommandType.Text;
            OrdersCommand.Connection = DBCon;
    
            // Opening the database connection
            DBCon.Open();
    
            // Retrieving customer information asynchronously
            CustAsyncResult = CustCommand.BeginExecuteReader();
    
            // Retrieving orders list asynchronously
            OrdersASyncResult = OrdersCommand.BeginExecuteReader();
    
            CustWHandle = CustAsyncResult.AsyncWaitHandle;
            OrdersWHandle = OrdersASyncResult.AsyncWaitHandle;
    
            // Filling Wait Handles array with the two wait handles we
            // are going to use in this code
            WHandles[0] = CustWHandle;
            WHandles[1] = OrdersWHandle;
    
                // We are only waiting for any of the two 
                // asynchronous process to finish running
                WHIndex = System.Threading.WaitHandle.WaitAny(WHandles);
    
                // The return value from the WaitAny method is
                // the array index of the Wait Handle that just 
                // finsihed running
                switch (WHIndex)
                {
                    case 0:
                        CustReader = CustCommand.EndExecuteReader(CustAsyncResult);
    
                        gvCustomers.DataSource = CustReader;
                        gvCustomers.DataBind();
                        break;
                    case 1:
                        OrdersReader = 
                           OrdersCommand.EndExecuteReader(OrdersASyncResult);
    
                        gvOrders.DataSource = OrdersReader;
                        gvOrders.DataBind();
                        break;
                }
            
            // Closing connection
            DBCon.Close();
        }
    </script>


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月27日 1:43
  • 移出循环,在这种情况下如何处理剩下的异步进程

    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月27日 4:20
  • 移出循环,在这种情况下如何处理剩下的异步进程

    please verify my account

    异步线程是后台线程,自己完成的。你一般无需获取结果。如果你一定要使得线程全部完成的话,根本没有必要使用异步了,或者使用WaitAll而不是WaitAny。

    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月28日 1:07
  • 如果你一定要使得线程全部完成的话,根本没有必要使用异步了,什么意思?深入讲解一下

    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月28日 7:20

全部回复

  • WHhandles是信号量,用于等待的。请问您如何使用的?

    另外,此处为什么用循环?我认为貌似没有必要。


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月26日 5:55
  • WHhandles是信号量,用于等待的,是什么意思?

    asp.net 4高级编程或者ado。net2.0技术内幕,都是这么用的,

    如下:waitAny(WaidHandles),这是一个静态方法,如果以数组的形式管理多个WaitHandle,就可以使用它。使用这个方法会等待所有的异步进程都结束,并且其WaitHandle位于传送给它的数组中。waitany()方法必须重复调用,为每个要处理的WaitHandle调用一次。

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Configuration" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            SqlConnection DBCon;
            SqlCommand OrdersCommand = new SqlCommand();
            SqlCommand CustCommand = new SqlCommand();
            SqlDataReader OrdersReader;
            SqlDataReader CustReader;
            IAsyncResult OrdersASyncResult;
            IAsyncResult CustAsyncResult;
    
            int WHIndex;
            System.Threading.WaitHandle[] WHandles = 
               new System.Threading.WaitHandle[2];
            System.Threading.WaitHandle OrdersWHandle;
            System.Threading.WaitHandle CustWHandle;
    
            DBCon = new SqlConnection();
            DBCon.ConnectionString =             
              ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;
    
            CustCommand.CommandText = 
               "SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste'";
    
            CustCommand.CommandType = CommandType.Text;
            CustCommand.Connection = DBCon;
    
            OrdersCommand.CommandText = 
                    "SELECT Customers.CompanyName, Customers.ContactName, " +
                    "Orders.OrderID, Orders.OrderDate, " +
                    "Orders.RequiredDate, Orders.ShippedDate " +
                    "FROM Orders, Customers " +
                    "WHERE Orders.CustomerID = Customers.CustomerID " +
                    "AND Customers.CompanyName = 'Alfreds Futterkiste' " +
                    "ORDER BY Customers.CompanyName, Customers.ContactName";
    
            OrdersCommand.CommandType = CommandType.Text;
            OrdersCommand.Connection = DBCon;
    
            // Opening the database connection
            DBCon.Open();
    
            // Retrieving customer information asynchronously
            CustAsyncResult = CustCommand.BeginExecuteReader();
    
            // Retrieving orders list asynchronously
            OrdersASyncResult = OrdersCommand.BeginExecuteReader();
    
            CustWHandle = CustAsyncResult.AsyncWaitHandle;
            OrdersWHandle = OrdersASyncResult.AsyncWaitHandle;
    
            // Filling Wait Handles array with the two wait handles we
            // are going to use in this code
            WHandles[0] = CustWHandle;
            WHandles[1] = OrdersWHandle;
    
            // Looping 2 times because there are 2 wait handles 
            // in the array
            for (int Index = 0; Index < 2; Index++ )
            {
                // We are only waiting for any of the two 
                // asynchronous process to finish running
                WHIndex = System.Threading.WaitHandle.WaitAny(WHandles);
    
                // The return value from the WaitAny method is
                // the array index of the Wait Handle that just 
                // finsihed running
                switch (WHIndex)
                {
                    case 0:
                        CustReader = CustCommand.EndExecuteReader(CustAsyncResult);
    
                        gvCustomers.DataSource = CustReader;
                        gvCustomers.DataBind();
                        break;
                    case 1:
                        OrdersReader = 
                           OrdersCommand.EndExecuteReader(OrdersASyncResult);
    
                        gvOrders.DataSource = OrdersReader;
                        gvOrders.DataBind();
                        break;
                }
            }
            // Closing connection
            DBCon.Close();
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title>The Wait Any Approach</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        <asp:GridView ID="gvCustomers" Width="100%" runat="server"></asp:GridView>
        <br /><br />
        <asp:GridView ID="gvOrders" Width="100%" AutoGenerateColumns="False"         
         runat="server">
           <Columns>
              <asp:BoundField HeaderText="Company Name" 
               DataField="CompanyName"></asp:BoundField>
              <asp:BoundField HeaderText="Contact Name" 
               DataField="ContactName"></asp:BoundField>
              <asp:BoundField HeaderText="Order Date" DataField="orderdate" 
               DataFormatString="{0:d}"></asp:BoundField>
              <asp:BoundField HeaderText="Required Date" DataField="requireddate" 
               DataFormatString="{0:d}"></asp:BoundField>
              <asp:BoundField HeaderText="Shipped Date" DataField="shippeddate" 
               DataFormatString="{0:d}"></asp:BoundField>
           </Columns>
        </asp:GridView>
        </div>
        </form>
    </body>
    </html>
    


    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月26日 10:48
  • 尝试直接移除For循环:

     protected void Page_Load(object sender, EventArgs e)
        {
            SqlConnection DBCon;
            SqlCommand OrdersCommand = new SqlCommand();
            SqlCommand CustCommand = new SqlCommand();
            SqlDataReader OrdersReader;
            SqlDataReader CustReader;
            IAsyncResult OrdersASyncResult;
            IAsyncResult CustAsyncResult;
    
            int WHIndex;
            System.Threading.WaitHandle[] WHandles = 
               new System.Threading.WaitHandle[2];
            System.Threading.WaitHandle OrdersWHandle;
            System.Threading.WaitHandle CustWHandle;
    
            DBCon = new SqlConnection();
            DBCon.ConnectionString =             
              ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;
    
            CustCommand.CommandText = 
               "SELECT * FROM Customers WHERE CompanyName = 'Alfreds Futterkiste'";
    
            CustCommand.CommandType = CommandType.Text;
            CustCommand.Connection = DBCon;
    
            OrdersCommand.CommandText = 
                    "SELECT Customers.CompanyName, Customers.ContactName, " +
                    "Orders.OrderID, Orders.OrderDate, " +
                    "Orders.RequiredDate, Orders.ShippedDate " +
                    "FROM Orders, Customers " +
                    "WHERE Orders.CustomerID = Customers.CustomerID " +
                    "AND Customers.CompanyName = 'Alfreds Futterkiste' " +
                    "ORDER BY Customers.CompanyName, Customers.ContactName";
    
            OrdersCommand.CommandType = CommandType.Text;
            OrdersCommand.Connection = DBCon;
    
            // Opening the database connection
            DBCon.Open();
    
            // Retrieving customer information asynchronously
            CustAsyncResult = CustCommand.BeginExecuteReader();
    
            // Retrieving orders list asynchronously
            OrdersASyncResult = OrdersCommand.BeginExecuteReader();
    
            CustWHandle = CustAsyncResult.AsyncWaitHandle;
            OrdersWHandle = OrdersASyncResult.AsyncWaitHandle;
    
            // Filling Wait Handles array with the two wait handles we
            // are going to use in this code
            WHandles[0] = CustWHandle;
            WHandles[1] = OrdersWHandle;
    
                // We are only waiting for any of the two 
                // asynchronous process to finish running
                WHIndex = System.Threading.WaitHandle.WaitAny(WHandles);
    
                // The return value from the WaitAny method is
                // the array index of the Wait Handle that just 
                // finsihed running
                switch (WHIndex)
                {
                    case 0:
                        CustReader = CustCommand.EndExecuteReader(CustAsyncResult);
    
                        gvCustomers.DataSource = CustReader;
                        gvCustomers.DataBind();
                        break;
                    case 1:
                        OrdersReader = 
                           OrdersCommand.EndExecuteReader(OrdersASyncResult);
    
                        gvOrders.DataSource = OrdersReader;
                        gvOrders.DataBind();
                        break;
                }
            
            // Closing connection
            DBCon.Close();
        }
    </script>


    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月27日 1:43
  • 移出循环,在这种情况下如何处理剩下的异步进程

    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月27日 4:20
  • 移出循环,在这种情况下如何处理剩下的异步进程

    please verify my account

    异步线程是后台线程,自己完成的。你一般无需获取结果。如果你一定要使得线程全部完成的话,根本没有必要使用异步了,或者使用WaitAll而不是WaitAny。

    ASP.NET Forum
    Other Discussion Forums
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月28日 1:07
  • 如果你一定要使得线程全部完成的话,根本没有必要使用异步了,什么意思?深入讲解一下

    please verify my account

    • 已标记为答案 lctk 2016年6月4日 16:00
    2015年8月28日 7:20