0

2 つのクラスがあります。1 つは Form1.cs と呼ばれ、もう 1 つは NoteThreader.cs と呼ばれ、両方のクラスの内容は次のとおりです。

Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace HitMachine
{
 public partial class Form1 : Form
 {
    public Form1()
    {
        InitializeComponent();
    }

    public void updateText(string theText)
    {
        label1.Text = theText;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        XML.LoadMP3.loadFile(XML.XmlParser.ParseDocument("music"));
        Threading.NoteThreader.createTimer();
    }
  }
}

NoteThreader.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    namespace HitMachine.Threading
    {
        public class NoteThreader
        {
            public static Thread createTimer()
            {
                Thread t = new Thread(threadDeligation);
                t.Start();

                return t;
            }

            public static int time = 0;

            static void threadDeligation()
            {
                for (; ; )
                {
                    Form1 a = new Form1();
                    a.updateText(time);
                    time++;
                }
            }
        }
    }

コードは例外やエラーなしで実行されます。ただし、テキストは更新されません。メソッドを呼び出しているスレッドがテキストを更新しているスレッドとは異なるためだと思いますか?

私はそれを呼び出そうとしましたが、そうすることができませんでした。threadDeligation で MessageBox を実行したところ、うまくいきました。

4

3 に答える 3

2

メソッドでは、ループが実行されるたびthreadDeligationに新しいインスタンスを作成しています。これは、あなたが見ているForm1インスタンスのテキストを変更しません。Form1

Form1の正しいインスタンスをメソッドに渡す必要がありますcreateTimer(そして、それをメソッドに渡しますthreadDeligation)。

次のように実行できます。

private void Form1_Load(object sender, EventArgs e)
{
    XML.LoadMP3.loadFile(XML.XmlParser.ParseDocument("music"));
    Threading.NoteThreader.createTimer(this);
}

その後:

public static Thread createTimer(Form1 theForm)
{
    Thread t = new Thread(() => threadDeligation(theForm));
    t.Start();
   return t;
}

public static int time = 0;

static void threadDeligation(Form1 theForm)
{
    for (; ; )
    {
         theForm.updateText(time);
         time++;
    }
}

これにより、コード内でオブジェクトを渡す方法の一般的なアイデアが得られるはずですが、UI 以外のスレッドからの UI 要素の更新はサポートされていないため、機能しませんBackgroundWorker代わりにクラスを使用する必要があります。

于 2013-09-05T16:43:11.533 に答える
1
for (; ; )
{
    Form1 a = new Form1();
    a.updateText(time);
    time++;
}
  1. 反復ごとに新しいForm1オブジェクトが作成されます。
  2. はどこa.Show();ですか?

タイマーの値を表示したい場合は、適切なForm1オブジェクトへの参照を保持する必要があります。

于 2013-09-05T16:38:36.950 に答える