我做一个程序,是捕捉网络数据包的,使用的是异步捕捉方法:
 mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                        new AsyncCallback(OnReceive), null);然后在窗口上用一个datagridview显示捕捉到的数据,在回调函数中,将捕捉到的数据添加到datagridview的数据源上,以达到显示的目的现在有一个问题是,当数据多了以后,垂直滚动条不会自动出现,我试过.Invalidate 和.Refresh方法,都不行,请问如何才能让滚动条自动出现,如果将窗口最大化,滚动条是可以出现的。
另外还有一个问题,如果在回调函数OnReceive中操作form上的控件,比如:dataGridView1.Refresh();会提示错误:“线程间操作无效,不是从创建控件datagridview1的线程上访问他”,这样要刷新就得用委托,
滚动条不能出现会不会和 是在 回调函数中修改datagridview的数据源有关。更奇怪的是我写的另外一个程序,异步使用ping测试:pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
pingSender.SendAsync(ipAddress);
在这个回调函数PingCompletedCallback中,却能操作form上的控件,比如richTextBox1.AppendText(str);
为什么同样是异步函数,一个可以操作主程序上的控件,另外一个不可以,请大侠帮忙看看

解决方案 »

  1.   

    因为你第一个使用了异步编程模式(APM)来实现异步的,它的异步操作是在另一个线程中运行的,然后你调用Ping的SendAsync方法是实现了基于事件的异步编程(EAP),然而在Ping的SendAsync方法内部实现了获取UI线程的同步上下文的代码,所以调用SendAsync方法不会出现第一种方式出现的错误,主要是因为SendAsync方法内部把操作控件方法交给了UI线程去执行,然而BeginReceive方法内部没有,所以会出现那样的异常,详细内容可以参考我的博客:
    [你必须知道的异步编程]——异步编程模型(APM)
    [你必须知道的异步编程]——基于事件的异步编程模式
      

  2.   


    另外,BeginReceive,有没有采用eap方式的函数呢
      

  3.   


    另外,BeginReceive,有没有采用eap方式的函数呢
    你可以调用Socket.ReceiveAsync方法,该方法就是对应的EAP方法,然后滚动条可以调用DataGridView.Update方法来更新数据来实现试试