2

こんにちは、TCP-IP 経由でいくつかの pictrue アドレスを取得し、画面に表示する非常に単純なプログラムを作成しました。私の問題は、写真を更新するたびにメモリが取り残され、本質的にメモリの過負荷になることです。

私は awnser を探し回っていて、関数 Dispose を使用する必要があるかもしれないと結論付けました。私の問題は、実装しようとすると次のエラーが発生することです。

エラー C2039: 'Dispose' : is not a member of 'System::Windows::Forms::PictureBox'

私が探しているのは、新しい画像をロードしたいときにメモリをクリアする正しい方法です。

これは私のコードです。私の問題を調べるのに時間がかかる人に感謝します

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    /// <summary>
    /// Summary for Form1
    ///
    /// WARNING: If you change the name of this class, you will need to change the
    ///          'Resource File Name' property for the managed resource compiler tool
    ///          associated with all .resx files this class depends on.  Otherwise,
    ///          the designers will not be able to interact properly with localized
    ///          resources associated with this form.
    /// </summary>
    public ref class Form1 : public System::Windows::Forms::Form
    {
    public:
        Form1(void)
        {

            InitializeComponent();
            pictureBoxArrayLeft->Resize(pictureBoxArrayLeft,15);
            pictureBoxArrayRight->Resize(pictureBoxArrayRight,15);
            IPAddress^ listenInterface = IPAddress::Any;//Parse("127.0.0.1");
            int listenPort = 12000;
            int bufferSize = 4096;
            sendBuffer = gcnew array<Byte>(bufferSize);
            receiveBuffer = gcnew array<Byte>(bufferSize);
            tcpServer = gcnew TcpListener(listenInterface, listenPort);
            // Start listening for connections
            tcpServer->Start();
            incomeText = "";
            connection_active = false;
            readyToRead = true;

            System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
            int loopRunner;
            loopRunner = 0;
            while(loopRunner < 15)
            {
                pictureBoxArrayLeft[loopRunner] = (gcnew System::Windows::Forms::PictureBox());
                (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBoxArrayLeft[loopRunner]))->BeginInit();
                // 
                // pictureBox1
                // 
                this->pictureBoxArrayLeft[loopRunner]->BackColor = System::Drawing::Color::Black;
                this->pictureBoxArrayLeft[loopRunner]->Location = System::Drawing::Point(0, (73*loopRunner));
                this->pictureBoxArrayLeft[loopRunner]->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"pictureBox1.Image")));
                this->pictureBoxArrayLeft[loopRunner]->Size = System::Drawing::Size(73,73);
                this->pictureBoxArrayLeft[loopRunner]->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
                this->pictureBoxArrayLeft[loopRunner]->TabIndex = 1;
                this->pictureBoxArrayLeft[loopRunner]->TabStop = false;
                this->pictureBoxArrayLeft[loopRunner]->Visible = true;

                this->Controls->Add(this->pictureBoxArrayLeft[loopRunner]);
                pictureBoxArrayLeft[loopRunner]->BringToFront();
                loopRunner++;
            }
            loopRunner = 0;
            while(loopRunner < 15)
            {
                pictureBoxArrayRight[loopRunner] = (gcnew System::Windows::Forms::PictureBox());
                (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBoxArrayRight[loopRunner]))->BeginInit();
                // 
                // pictureBox1
                // 
                this->pictureBoxArrayRight[loopRunner]->BackColor = System::Drawing::Color::Black;
                this->pictureBoxArrayRight[loopRunner]->Location = System::Drawing::Point((1342-73), (73*loopRunner));
                this->pictureBoxArrayRight[loopRunner]->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"pictureBox1.Image")));
                this->pictureBoxArrayRight[loopRunner]->Size = System::Drawing::Size(73,73);
                this->pictureBoxArrayRight[loopRunner]->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
                this->pictureBoxArrayRight[loopRunner]->TabIndex = 1;
                this->pictureBoxArrayRight[loopRunner]->TabStop = false;
                this->pictureBoxArrayRight[loopRunner]->Visible = true;

                this->Controls->Add(this->pictureBoxArrayRight[loopRunner]);
                pictureBoxArrayRight[loopRunner]->BringToFront();
                loopRunner++;
            }
        }
        void pictures(String^ incomeText)
        {
            readyToRead = false;
            int counter;
            for(counter = 0; counter < 15; counter++)
            {
                pictureBoxArrayLeft[counter]->Visible = false;
                pictureBoxArrayRight[counter]->Visible = false;
            }

            System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
            String^ tempstring;
            String^ tempstring2;

            counter = 0;
            pictureBox1->Image = pictureBox1->Image->FromFile(incomeText->Substring(0,incomeText->IndexOf(L"#",0)));
            tempstring = incomeText->Substring(incomeText->IndexOf(L"#",0)+1);

            while(tempstring != L"")
            {
                tempstring2 = tempstring->Substring(0,tempstring->IndexOf(L"#",0));

                pictureBoxArrayLeft[counter]->Image = (cli::safe_cast<System::Drawing::Image^  >(Image::FromFile(tempstring2)));
                pictureBoxArrayRight[counter]->Image = (cli::safe_cast<System::Drawing::Image^  >(Image::FromFile(tempstring2)));

                pictureBoxArrayLeft[counter]->Visible = true;
                pictureBoxArrayRight[counter]->Visible = true;

                tempstring = tempstring->Substring(tempstring->IndexOf(L"#",0)+1);
                counter++;
            }   
            readyToRead = true;
        }
        void Send(String^ outgoing)
        {
            if(connection_active == true)
            {
                sendBuffer = System::Text::Encoding::ASCII->GetBytes(outgoing);
                tcpStream->Write(sendBuffer,0,sendBuffer->Length);
            }
        }
        void StartIfPending()
        {
                if(tcpServer->Pending())
                {
                    // Wait for a client connection
                    tcpClient = tcpServer->AcceptTcpClient();
                    // Get the NetworkStream so we can do Read and Write on the client connection
                    tcpStream = tcpClient->GetStream(); 
                    connection_active = true;
                    IPEndPoint^ ep = safe_cast<IPEndPoint^>(tcpClient->Client->RemoteEndPoint);
                }
                else
                {
                }
        }
        void Service()
        {
            StartIfPending();

            String^ incomeText = Recieve();
            if(incomeText != "" && incomeText != "<<") //check for empty String^ or empty command
            {
                if(readyToRead == true)
                {
                    pictures(incomeText);
                }
            } 
        }
        String^ Recieve()
        {
            if(connection_active == true)
            {
                try
                {   
                    // Receive the data
                    if(tcpStream->DataAvailable)
                    {
                        // Read some data
                        count = tcpStream->Read(receiveBuffer, 0, 4096);//nextReadCount);

                        // Display what we read
                        String^ inBufferString = System::Text::Encoding::ASCII->GetString(receiveBuffer, 0, count);
                        return inBufferString;
                    }
                    else
                    {
                        return "";
                    }
                }
                catch (SocketException^ err)
                {
                    // Exceptions on the TcpListener are caught here
                }

                catch (IO::IOException^ err)
                {
                    // Exceptions on the NetworkStream are caught here
                }
            }
            else
            {
                return "";
            }
        }
    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~Form1()
        {
            if (components)
            {
                delete components;
            }
        }
    private: array<System::Windows::Forms::PictureBox^>^  pictureBoxArrayLeft;
    private: array<System::Windows::Forms::PictureBox^>^  pictureBoxArrayRight;
    private: TcpListener^ tcpServer;
    private: TcpClient^ tcpClient;
    private: NetworkStream^ tcpStream;
    private: array<Byte>^ sendBuffer;
    private: array<Byte>^ receiveBuffer;
    private: array<Byte>^ byteCount;
    private: int count;
    private: bool connection_active;
    private: String^ incomeText;  
    private: bool readyToRead;  
    private: System::Windows::Forms::Timer^  timer1;
    private: System::Windows::Forms::PictureBox^  pictureBox1;
    private: System::ComponentModel::IContainer^  components;

    protected: 


    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->components = (gcnew System::ComponentModel::Container());
            System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
            this->timer1 = (gcnew System::Windows::Forms::Timer(this->components));
            this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
            (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->BeginInit();
            this->SuspendLayout();
            // 
            // timer1
            // 
            this->timer1->Enabled = true;
            this->timer1->Tick += gcnew System::EventHandler(this, &Form1::timer1_Tick);
            // 
            // pictureBox1
            // 
            this->pictureBox1->BackColor = System::Drawing::Color::Black;
            this->pictureBox1->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"pictureBox1.Image")));
            this->pictureBox1->Location = System::Drawing::Point(2, -1);
            this->pictureBox1->Name = L"pictureBox1";
            this->pictureBox1->Size = System::Drawing::Size(1342, 730);
            this->pictureBox1->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
            this->pictureBox1->TabIndex = 1;
            this->pictureBox1->TabStop = false;
            // 
            // Form1
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(1344, 730);
            this->Controls->Add(this->pictureBox1);
            this->Name = L"Form1";
            this->Text = L"Form1";
            (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->EndInit();
            this->ResumeLayout(false);

        }
#pragma endregion
    private: System::Void timer1_Tick(System::Object^  sender, System::EventArgs^  e) 
             {
                 Service();
             }
};
}
4

2 に答える 2

2

C++/CLI では、Dispose を明示的に呼び出しません。代わりに、deleteC++ オブジェクトの場合と同様に、オブジェクトに対して a を実行します。コンパイラは、舞台裏で Dispose の呼び出しでそれを変更します。

于 2013-01-17T16:16:53.180 に答える
1

C++/CLI の設計者は、C++ で RAII パターンを救出するために多大な努力をしました。マネージ言語で解決するのは難しい問題です。IDisposable インターフェイスを言語自体にカプセル化することで、これを実現しました。また、完全に非表示にすると、使用しようとするとコンパイル エラーが発生します。マネージ オブジェクトの削除演算子は、クラス オブジェクトが実装している場合、IDisposable::Dispose() メソッドを呼び出します。ref クラスの ~destructor は Dispose() メソッドを実装し、GC::SuppressFinalize() 呼び出しは自動生成されます。!finalizer は、ガベージ コレクターがオブジェクトに到達するたびにオブジェクトが実際に破棄されるときに実行されるものです。

Image プロパティへの代入の適切な呪文は次のようになります。

    delete pictureBox1->Image;   // Dispose the existing bitmap, if any
    pictureBox1->Image = pictureBox1->Image->FromFile(...);

画像をクリアしたい場合は、次のように記述します。

    delete pictureBox1->Image;
    pictureBox1->Image = nullptr;
于 2013-01-17T16:33:19.653 に答える