首页 新闻 会员 周边

关于WaitHandle.WaitAny

0
悬赏园豆:5 [已解决问题] 解决于 2016-06-04 22:43
请问两个异步查询,在一个循环中使用WaitHandle.WaitAny,返回一个异步查询后,索引是0,再次循环的时候,返回的索引还能是0吗?

如下:

string strConn, strSQL;
             SqlConnection cnCustomers, cnOrdes;
             SqlCommand cmdCustomers, cmdOrders;
             IAsyncResult[] iasyncresults = new IAsyncResult[2];
             WaitHandle[] waithandles = new WaitHandle[2];

            strConn = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True ;Asynchronous Processing=True;";
             cnCustomers = new SqlConnection(strConn);
             cnCustomers.Open();
             cnOrdes = new SqlConnection(strConn);
             cnOrdes.Open();
             strSQL = "WaitFor delay '00:00:10';" +
                 "select top 10 customerID from Customers";
             cmdCustomers = new SqlCommand(strSQL, cnCustomers);
             iasyncresults[0] = cmdCustomers.BeginExecuteReader(null, cmdCustomers, CommandBehavior.CloseConnection);
             waithandles[0] = iasyncresults[0].AsyncWaitHandle;
             strSQL = "Waitfor delay '00:00:10'; select top 10  orderID from orders";
             cmdOrders = new SqlCommand(strSQL, cnOrdes);
             iasyncresults[1] = cmdOrders.BeginExecuteReader(null, cmdOrders, CommandBehavior.CloseConnection);
             waithandles[1] = iasyncresults[1].AsyncWaitHandle;
             for (int intCounter = 0; intCounter < waithandles.Length; intCounter++)
             {
                 int intIndex = WaitHandle.WaitAny(waithandles);
                 SqlCommand cmd = (SqlCommand)iasyncresults[intIndex].AsyncState;
                 Console.WriteLine(cmd.CommandText);
                 
                 using (SqlDataReader rdr = cmd.EndExecuteReader(iasyncresults[intIndex]))
                 {
                     while (rdr.Read())
                     {
                         Console.WriteLine(rdr[0]);

                    }
                     rdr.Close();

                }



            }
博学多思的主页 博学多思 | 初学一级 | 园豆:76
提问于:2015-08-25 15:53
< >
分享
最佳答案
0

收获园豆:5
Launcher | 高人七级 |园豆:45045 | 2015-08-25 15:56

我想问一下这段代码有什么问题,就是在一个循环中使用WaitHandle.WaitAny,返回一个异步查询后,索引是0,再次循环的时候,返回的索引还能是0,不明白咋回事?按理说在WaitHandle.WaitAny返回一个索引后,再次循环应该把原来的异步的索引去掉,现在是同一个,解答一下

博学多思 | 园豆:76 (初学一级) | 2015-08-25 16:02

@博学多思: 如果第一次返回是 0 ,那么第二次返回也应该是 0,这才是按理说 。“再次循环应该把原来的异步的索引去掉”这不是按理说,这是你自己想象的。

 

https://msdn.microsoft.com/en-us/library/tdykks7z(v=vs.110).aspx

This method returns when any handle is signaled. If more than one object becomes signaled during the call, the return value is the array index of the signaled object with the smallest index value of all the signaled objects.

根据 MSDN 上对此方法的解释,如果它返回,它总是返回最小的索引。因此,当第一次循环返回 0 后,第二次循环时,就算索引 1 处的 handle 处于 signaled 状态,它也应该返回 0 ,因为 0 < 1 啊!

Launcher | 园豆:45045 (高人七级) | 2015-08-25 16:29

@Launcher: 不应该呀,好像不是这个原因?调试运行,结果不同

博学多思 | 园豆:76 (初学一级) | 2015-08-25 16:57

@博学多思: 结果怎么个不同法?

Launcher | 园豆:45045 (高人七级) | 2015-08-25 17:08

@Launcher: 

 

调试正常运行,不调适报错,调试结果如下

博学多思 | 园豆:76 (初学一级) | 2015-08-25 17:50

@博学多思: 这是你的运行结果,我们讨论的是 WaitHandle.WaitAny 的问题。请将 int intIndex = WaitHandle.WaitAny(waithandles); 中的 intIndex 的值给打印出来。

Launcher | 园豆:45045 (高人七级) | 2015-08-25 17:54

@博学多思: 你问的问题是:请问两个异步查询,在一个循环中使用WaitHandle.WaitAny,返回一个异步查询后,索引是0,再次循环的时候,返回的索引还能是0吗?

然后我回答你,这个结果是正确的!第一次是 0 ,第二次肯定是 0。

然后你回答我:不应该呀,好像不是这个原因?调试运行,结果不同。

那么我就想知道你用什么来否定我的回答(然后我回答你,这个结果是正确的!第一次是 0 ,第二次肯定是 0)。所以,请输出 intIndex 值。

Launcher | 园豆:45045 (高人七级) | 2015-08-25 17:56

@Launcher: 

博学多思 | 园豆:76 (初学一级) | 2015-08-25 18:02

@博学多思: 看我之前的回答:

https://msdn.microsoft.com/en-us/library/tdykks7z(v=vs.110).aspx

This method returns when any handle is signaled. If more than one object becomes signaled during the call, the return value is the array index of the signaled object with the smallest index value of all the signaled objects.

根据 MSDN 上对此方法的解释,如果它返回,它总是返回最小的索引。因此,当第一次循环返回 0 后,第二次循环时,就算索引 1 处的 handle 处于 signaled 状态,它也应该返回 0 ,因为 0 < 1 啊!

你这中文阅读能力怎么这么差!!!!!!!!!!!

我说了“如果它返回,它总是返回最小的索引”,你截图先输出的 1,说明索引 1 处的 handle 处于 signaled 状态,而索引 0 处的没有,所以返回最小的处于 signaled 状态的 handle 的索引 1。第二次循环的时,根据你的结果来看,索引 0 处的 handle 处于 signaled 状态了,所以,虽然索引 1 处的 handle 比索引 0 处的 handle 更早进入 signaled 状态,但是根据“如果它返回,它总是返回最小的索引”原则,这时候会返回 0 。

 

等你啥时候第一次循环得到 0 ,而第二次循环得到 1 时,你再来否定我的回答吧!

Launcher | 园豆:45045 (高人七级) | 2015-08-25 18:06

@Launcher: 

博学多思 | 园豆:76 (初学一级) | 2015-08-25 18:08

@博学多思: 等你啥时候第一次循环得到 0 ,而第二次循环得到 1 时,你再来否定我的回答吧!

Launcher | 园豆:45045 (高人七级) | 2015-08-25 18:10

@Launcher: 

返回最小索引,是这句话吗?

博学多思 | 园豆:76 (初学一级) | 2015-08-25 18:40

@Launcher: 当任何句柄都收到信号时,此方法返回。如果在调用期间有多个对象变为终止,则返回值为所有终止对象中具有最小索引值的终止对象的数组索引。在某些实现中,如果传递的句柄超过 64 个,将引发 NotSupportedException

 

当任何句柄都收到信号时:是什么意思?

如果在调用期间有多个对象变为终止,是什意思?

解答一下

 

 

博学多思 | 园豆:76 (初学一级) | 2015-08-25 21:59

@Launcher: 

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>

请问这是怎么回事?分析一下

博学多思 | 园豆:76 (初学一级) | 2015-08-26 19:09

@博学多思: 他跟你一样,写错了!就这么回事。

Launcher | 园豆:45045 (高人七级) | 2015-08-27 09:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册