0

ボタンをクリックすると、スレッドで別のウィンドウフォーム(form2)を開きたいウィンドウフォーム(Form1)があります。

スレッドで開きたいのは、起動時に1万行以上のファイルの構文を読み取って色付けするため、約5〜6分かかるからです。

私の問題は、それを行う「適切な」方法がわからないことです。私はそれを行う方法を見つけて正しく動作しますが、Form2 がその処理にどれだけ進んでいるかを示す進行状況バーを表示できるようにしたいと考えています。(おそらくバックグラウンド ワーカー オブジェクトを使用)

これが私のレイアウトです

Form1 には RichTextBoxes と 1 つのボタンがあり、ボタンをクリックすると、form1 の rtb のテキストに色を付ける別のスレッドでフォームが開きます。

Form2 にも Rtb があります。この rtb には、行を処理し、別のスレッドで実行したい作業を行う ProcessAllLines メソッドがあります。

これが私が困難を抱えていると思う理由です。フォームが読み込まれるのを待っている間、テキストボックスは作業を行っています。

Form2を開く方法は次のとおりです。

    private void button1_Click(object sender, EventArgs e)
    {
        ColoringThread colorer = new ColoringThread(this.m_bruteView.Text);
        Thread theThread = new Thread(new ThreadStart(colorer.OpenColorWindow));
        theThread.Start();
    }

    public class ColoringThread
    {
        string text;
        public ColoringThread(string initText)
        {
            text = initText;
        }
        public void OpenColorWindow()
        {
            Form2 form2 = new Form2(text);
            form2.ShowDialog();
        }
    };

そして、これが form2 がどのように機能するかです:

    string initText;
    public Form2(string initTextInput)
    {
        initText = initTextInput;
        InitializeComponent();
    }


private void InitializeComponent()
    {
        this.m_ComplexSyntaxer = new ComplexSyntaxer.ComplexSyntaxer();
        this.SuspendLayout();
        // 
        // m_ComplexSyntaxer
        // 
        this.m_ComplexSyntaxer.Dock = System.Windows.Forms.DockStyle.Fill;
        this.m_ComplexSyntaxer.Location = new System.Drawing.Point(0, 0);
        this.m_ComplexSyntaxer.Name = "m_ComplexSyntaxer";
        this.m_ComplexSyntaxer.Size = new System.Drawing.Size(292, 273);
        this.m_ComplexSyntaxer.TabIndex = 0;
        this.m_ComplexSyntaxer.Text = initText;
        this.m_ComplexSyntaxer.WordWrap = false;

        // THIS LINE DOES THE WORK
        this.m_ComplexSyntaxer.ProcessAllLines();
        // 
        // Form2
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(292, 273);
        this.Controls.Add(this.m_ComplexSyntaxer);
        this.Name = "Form2";
        this.Text = "Form2";
        this.ResumeLayout(false);
    }

そして、ここで作業が行われます:

    public void ProcessAllLines()
    {
        int nStartPos = 0;
        int i = 0;
        int nOriginalPos = SelectionStart;
        while (i < Lines.Length)
        {
            m_strLine = Lines[i];
            m_nLineStart = nStartPos;
            m_nLineEnd = m_nLineStart + m_strLine.Length;
            m_nLineLength = m_nLineEnd - m_nLineStart;

            ProcessLine(); // This colors the current line!
            i++;

            nStartPos += m_strLine.Length + 1;
        }
        SelectionStart = nOriginalPos;
    }

Sooo、この form2 を開いて Form1 に進行状況を報告してユーザーに表示する「適切な」方法は何ですか? (これは正しいことではないと言われたので、どうやら「クロススレッド」違反が発生するのでしょうか?)

4

2 に答える 2

2

スレッドで開きたいのは、起動時に1万行以上のファイルの構文を読み取って色付けするため、約5〜6分かかるからです。

別のスレッドでデータを読み取らずに、UI 自体を最初のフォームと同じスレッドに保持するのはなぜですか?

私の経験では、UI 操作に 1 つのスレッドのみを使用すると、作業が大幅に簡素化されます。

データを読み取るために新しいスレッドを開始する方法については、さまざまなオプションがあります。

  • 使用できますBackgroundWorker。これにより、おそらく進捗報告がより簡単になります。詳細については、MSDN の記事を参照してください
  • 新しいThreadものを直接作成して開始する
  • スレッドプールスレッドを使用するThreadPool.QueueUserWorkItem
  • .NET 4 を使用している場合は、Task.Factory.StartNew
于 2012-08-17T19:28:15.990 に答える
1

私の意見では、他の形式は別の明示的なスレッドで実行する必要はありません。

長い作業を別のスレッド (またはバックグラウンド ワーカー) で実行したいのは確かですが、別のフォームを呼び出したいだけで、そのフォームは別のスレッド (またはバックグラウンド ワーカー) でタスクを実行します。

于 2012-08-17T19:28:29.797 に答える