0

我的应用程序启动并绘制 MDI 父窗体。此时,它等待事件发生。为了启动主循环,用户必须单击工具栏按钮。这调用了主处理例程,这里是代码。

    private void MainAPRSTW_Main()
        {
        //frmSplash objfrmSplash = new frmSplash();
        //objfrmSplash.ShowDialog();

        //this is the main list
        TopNodeList MainList = new TopNodeList(this);

        //setup the filter
        FilterList CallFilter = new FilterList();
        CallFilter.ReadPassList();
        CallFilter.ReadBlockList();

        //load what's in the cache
        MainList.ReadCache(this);

        //initiate the Socket
        Socket server = new Socket(AddressFamily.InterNetwork,
                                   SocketType.Stream,
                                   ProtocolType.Tcp);

        //initiate the endpoints
        IPEndPoint AGWPEServer=new IPEndPoint(IPAddress.Parse(AGWIPAddress), AGWPort);

        try
            {
            server.Connect(AGWPEServer);
            }
        catch (SocketException e)
            {
            System.Windows.Forms.MessageBox.Show("Unable to connect to server.");
            junk = e.ToString();//this keeps the compiler from complaining
            return;
            }

        //send command to enable monitor frames
        try
            {
            server.Send(MonitorCommand, 36, SocketFlags.None);
            }
        catch (SocketException e)
            {
            System.Windows.Forms.MessageBox.Show("Unable to write monitor command.");
            junk = e.ToString();//this keeps the compiler from complaining
            return;
            }

        //-problem code starts here--------------------------------------------
        while (TerminateFlag == false)
            {
            if (server.Available > 35)
                {
                //only go here if we have enough data available to process
                //get the next header
                TelemetryHeader.readHeader(server);

                //read the rest of the packet and ignore
                int recv = server.Receive(AGWServerData,
                                          TelemetryHeader.MessageSize,
                                          SocketFlags.None);

                //Is it a telemetry packet?
                if (Detector.isTelemetry(AGWServerData,TelemetryHeader.SourceCallsign))
                    {
                    if (CallFilter.Find(TelemetryHeader.SourceCallsign))
                        MainList.ProcessPacket(AGWServerData, Detector, this);
                    }
                }//close If (server.Available).......
            }//close while (terminateflag)......
        //-problem code stops here-------------------------------------------
        }//close MainAPRSTW_Main

您可以看到我在哪里描述了问题代码。如果我保留此代码,则子窗体只会部分填充,并且程序将无响应。这是一个屏幕截图。

http://www.blandranch.net/Files/broke.jpg

如果我注释掉问题代码,所有子窗体都会绘制。这是那个屏幕截图。

http://www.blandranch.net/Files/working.jpg

所以对我来说很明显我需要做一些不同的事情。我猜这个循环太紧了。是这种情况还是有其他问题?

问题是,什么是正确的方法?我使用后台工作者吗?还有其他方法吗?

查克

4

1 回答 1

0

使用 BackgroundWorker 或线程池。UI 线程不应该被阻塞。进入这样的循环会阻止 UI 线程能够处理 UI 更新消息(如重绘控件或更新新条目)。

在您的情况下,我建议使用 BeginConnect 和 BeginSend 而不是 Connect 并使用异步 IO 来进行后台处理。

于 2012-08-03T20:21:52.327 回答