0

テキスト ボックスを設定して表示するフォームがあります。フォーム ロード メソッドでは、完全に別のクラス名から新しいスレッドを開始していますProcessing

    private void Form1_Load(object sender, EventArgs e)
    {
        Processing p = new Processing();
        Thread processingThread = new Thread(p.run);
        processingThread.Start();
    }

これが処理クラスです。Utilities私がやりたいのは、必要なクラスからテキストボックスを更新できるようにするクラス内のメソッドを作成することです:

public class Processing
{        
    public void run()
    {               
        Utilities u = new Utilities();

        for (int i = 0; i < 10; i++)
        {
            u.updateTextBox("i");
        }                    
    }

 }

そして最後にUtilitesクラス:

class Utilities
{
    public void updateTextBox(String text) 
    {
        //Load up the form that is running to update the text box
        //Example:  
        //Form1.textbox.appendTo("text"):
    }
}

Invokeメソッド、SynchronizationContextバックグラウンドスレッド、その他すべてについて読みましたが、ほとんどすべての例はForm、別のクラスからではなく、スレッドと同じクラスのメソッドを使用しています。

4

2 に答える 2

3

このProgressクラスは、このために特別に設計されています。

フォームで、バックグラウンド スレッドを開始する前に、Progressオブジェクトを作成します。

Progress<string> progress = new Progress<string>(text => textbox.Text += text);

次に、そのprogressオブジェクトをワーカー メソッドに提供します。

Processing p = new Processing();
Thread processingThread = new Thread(() => p.run(progress));
processingThread.Start();

その後、プロセッサは進行状況を報告できます。

public class Processing
{        
    public void run(IProgress<string> progress)
    {               
        for (int i = 0; i < 10; i++)
        {
            Thread.Sleep(1000);//placeholder for real work
            progress.Report("i");
        }                    
    }
}

Progressクラスは、内部的に、最初に作成された同期コンテキストをキャプチャし、そのコンテキストへの呼び出しの結果として呼び出されたすべてのイベント ハンドラーをマーシャリングしReportます。代理。また、すべての UI コードがフォームの定義内にとどまり、すべての非 UI コードがフォームの外にあることが保証されるため、UI コードからビジネス コードを分離するのに役立ちます (これは非常に良いことです)。

于 2013-02-28T19:51:33.373 に答える
2

次のように、Form1 クラスにメソッドを追加AppendText()します。

public void AppendText(String text) 
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<string>(AppendText), new object[] { text });
        return;
    }
    this.Textbox.Text += text;
}

次に、ユーティリティ クラスから、次のように呼び出します。

class Utilities
{
    Form form1;   // I assume you set this somewhere

    public void UpdateTextBox(String text) 
    {
        form1.AppendText(text);
    }
}

ここで見つけることができる .NET でのスレッド化に関する非常に優れた包括的なレビューがあります: Multi-Threading in .NETWinForms でのスレッド化に関するセクションがあり、非常に役立ちます。

于 2013-02-28T19:52:33.927 に答える