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

ですから、私は何か違うことをする必要があることは明らかです。ループがきつすぎると思います。それは事実ですか、それとも間違っている何か他のものがありますか?

問題は、正しいアプローチは何ですか?Backgroundworkerを使用しますか?別の方法はありますか?

チャック

4

1 に答える 1

0

BackgroundWorker またはスレッド プールを使用します。UI スレッドは決してブロックされるべきではありません。このようなループに入ると、UI スレッドが UI 更新メッセージ (コントロールの再描画や新しいエントリの更新など) を処理できなくなります。

あなたの場合、 Connect の代わりに BeginConnect と BeginSend を使用し、非同期 IO を使用してバックグラウンドで処理を行うことをお勧めします。

于 2012-08-03T20:21:52.327 に答える