C# TCP客户端填充填充绑定DataGridView的DataTable,UI无响应

C# TCP客户端填充填充绑定DataGridView的DataTable,UI无响应,c#,multithreading,user-interface,begininvoke,C#,Multithreading,User Interface,Begininvoke,首先,我正在使用VisualStudio10和编写Windows窗体应用程序。我对C#中的线程没有经验 我有一个C#应用程序,它使用我的C#DLL监听网络流,并解析它接收到的数据。解析后的数据用于插入/更新Datatable的行,Datatable绑定到位于主窗体上的DataGridView 我已经用一个在DLL内部启动的工作线程尝试了这一点。绑定到DataGridView的DataTable作为参数传递给DLL。然后线程开始。线程函数是这样的 private void ListenThread

首先,我正在使用VisualStudio10和编写Windows窗体应用程序。我对C#中的线程没有经验

我有一个C#应用程序,它使用我的C#DLL监听网络流,并解析它接收到的数据。解析后的数据用于插入/更新Datatable的行,Datatable绑定到位于主窗体上的DataGridView

我已经用一个在DLL内部启动的工作线程尝试了这一点。绑定到DataGridView的DataTable作为参数传递给DLL。然后线程开始。线程函数是这样的

private void ListenThread()

    {
        Thread.CurrentThread.CurrentCulture =
            System.Globalization.CultureInfo.InvariantCulture;
        while (m_Active)
        {
            Thread.Sleep(100);
            int lData = m_Stream.Read(m_Buffer, 0,
                  m_Client.ReceiveBufferSize);
            String myString = Encoding.UTF7.GetString(m_Buffer);
            myString = myString.Substring(0, lData);
            ParseString(myString);

        }
    }
ParseString()方法解析数据并向DataTable插入一行或更新现有行

这段代码运行得很好,直到我尝试用CTRL+F5而不是F5来运行应用程序。几秒钟后,用户界面变得无响应,它开始填充网格

我在谷歌上搜索了一下,发现我应该使用BeginInvoke来防止UI冻结。但我没有成功地实现这一点

我试过类似的东西

TCPListener Listener = new TCPListener(ListenThread);
IAsyncResult result = Listener.BeginInvoke(null, null);
而不是

Thread m_tidListen = new Thread(new ThreadStart(ListenThread));
但它的工作原理是一样的。仍然无法使用“无调试模式”


我应该如何使用BeginInvoke实现这一点?或者我应该尝试其他方法吗?

既然您已经在构建winforms了,那么您最好使用一个。它们是为在后台做一些事情而设计的,同时保持表单的响应性。例如:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        //do your time consuming stuff
        while (m_Active)
        {
            Thread.Sleep(100);
            int lData = m_Stream.Read(m_Buffer, 0,
                  m_Client.ReceiveBufferSize);
            String myString = Encoding.UTF7.GetString(m_Buffer);
            e.result = myString.Substring(0, lData);

            ParseString(e.Result.ToString());
        }

    }

 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //update your UI if needed
    }

既然您已经在构建winforms,那么您最好使用一个用于这种事情的。它们是为在后台做一些事情而设计的,同时保持表单的响应性。例如:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        //do your time consuming stuff
        while (m_Active)
        {
            Thread.Sleep(100);
            int lData = m_Stream.Read(m_Buffer, 0,
                  m_Client.ReceiveBufferSize);
            String myString = Encoding.UTF7.GetString(m_Buffer);
            e.result = myString.Substring(0, lData);

            ParseString(e.Result.ToString());
        }

    }

 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //update your UI if needed
    }

谢谢你的帮助。但在这段代码中,我认为它将在获取所有数据后转到ParseString()方法。但这条小溪并没有尽头。应用程序将侦听流,直到关闭为止。它读取一个数据块,解析它,更新Datatable并监听流。此循环将继续。BackGroundWorker也有相同的结果。UI在几秒钟后会像以前一样没有响应。还有什么不对劲?使用从网络流检索的数据填充DataGridView的方法正确吗?@SCHWARZXXL:Hmm。。我认为这可能与“启动而不调试”更相关。在“释放”模式下运行时是否也会发生这种情况?尝试关闭一些在后台运行的应用程序(如病毒扫描程序)。我会尝试。但是你认为我应该在这里使用BeginInvoke机制吗?我也试过了。但我想我不能正确地实现它。@SCHWARZXXL:是的,但我更喜欢backgroundworker;它使用了与BeginInvoke相同的基本原则,但更易于使用。感谢您的帮助。但在这段代码中,我认为它将在获取所有数据后转到ParseString()方法。但这条小溪并没有尽头。应用程序将侦听流,直到关闭为止。它读取一个数据块,解析它,更新Datatable并监听流。此循环将继续。BackGroundWorker也有相同的结果。UI在几秒钟后会像以前一样没有响应。还有什么不对劲?使用从网络流检索的数据填充DataGridView的方法正确吗?@SCHWARZXXL:Hmm。。我认为这可能与“启动而不调试”更相关。在“释放”模式下运行时是否也会发生这种情况?尝试关闭一些在后台运行的应用程序(如病毒扫描程序)。我会尝试。但是你认为我应该在这里使用BeginInvoke机制吗?我也试过了。但我想我不能正确地实现它。@SCHWARZXXL:是的,但我更喜欢backgroundworker;它使用了与BeginInvoke相同的基本原理,但更易于使用。