-1

文字列からconsole.beepを使用して音楽を再生する小さなWindowsフォームプログラムがあります。新しいスレッド「t」に設定された文字列再生ビット(基本的に文字ごとに文字列を通過し、適切な音符を再生する for ループ)があります。「再生」ボタンを押すと、スレッドが開始され、ボタンが「停止」ボタンに変わります。音楽の再生中にこの「停止」ボタンを押すと、音楽が停止し、ボタンが再生に戻ります (「終了」メソッドを呼び出すことによって)。私の問題は、新しいスレッドで実行されているループに、ループがコースを実行し、曲が終わったときの「終了」メソッドしかし、ループの後にfinished()を置くと、「非静的フィールドにはオブジェクト参照が必要です」というエラーが表示されます。

ボタンを押したときのコードは次のとおりです...

//This is the method for when the "start" button is clicked
public void button1_Click(object sender, EventArgs e) 
    {
        if (music == null) { return; }

        if (button1.Text == "Play")
        {
            // it makes a new thread which calls my "parse" method which 
            // interprets the music and then calls "playnote" to play it.
            Thread t = new Thread(parse); 
            t.Start();
            button1.Text = "Stop";
        }
        else 
        {
            finished();
        }
    }

    public void finished()
    {
        stop = true;
        button1.Text = "Play";
    }

助言がありますか?

よろしくお願いします!

編集:ありがとうございました!! バックグラウンド ワーカーの ATM を理解する時間がないので、今は開始ボタンと停止ボタンを別々に用意しています。:p

4

7 に答える 7

4

これは、BackgroundWorker スレッドを使用したほうがよいと思います。そうすれば、イベントでfinished()メソッドを呼び出すことができます。RunWorkerCompleted

于 2012-06-14T18:31:56.127 に答える
1

parse() メソッドは静的ですか? インスタンスを提供せずに静的メソッドから finished() を呼び出そうとしているようです。そのため、「非静的フィールドにはオブジェクト参照が必要です」というエラーが発生しています。

于 2012-06-14T18:31:54.223 に答える
0

必要なことは、メイン スレッドでイベントを発生させて、終了したメソッドを呼び出すことです。フォーム クラスでイベントとデリゲートを宣言することから始めます。

public delegate void CallFinishedEventHandler();
public event CallFinishedEventHandler CallFinished;

次に、イベントが発生したときに呼び出されるイベント ハンドラーを作成し、その中で、完了したメソッドを呼び出します。

void Form1_CallFinished()
{
  Finished();
}

次に、フォーム コンストラクターで、イベント ハンドラーをイベントに接続します。

public Form1()
{
    CallFinished += Form1_CallFinished;
}

最後に、音楽再生コードで、終了したメソッドを (UI スレッドで) 呼び出す場合は、UI スレッドでイベントが発生するようにイベントを呼び出します。

this.Invoke(CallFinished);
于 2012-06-14T18:51:36.480 に答える
0

あなたがする必要があるのは、作成されたスレッドがそれを作成したオブジェクト (つまり、"button1_Click()" メソッドのスコープ内の "this") にアクセスできることを確認することです。これを行うには、t.Start() の代わりに t.Start(this) を呼び出します。そうすることで、「finished()」メソッドを呼び出すことができるオブジェクトをスレッドに渡すことになります。次に、「parse」メソッドが Object 型の引数を取ることを確認する必要があります。その際、「t.Start(this)」を呼び出すと、「parse」メソッドは「this」をパラメーターとして受け取ります。適切な型に変換するには、単純なキャストが必要です。ここで、スレッドで曲を停止したい場合は、キャストされたパラメーターで「finish()」メソッドを呼び出すだけです。したがって、コードは次のようになります。

public void parse(object o) { MyClass c = o as MyClass; // MyClass をクラスの名前に置き換えます

[...] // play music here

c.finished();  // call finished when you are done

}

public void button1_Click(オブジェクト送信者, EventArgs e) { [...]

スレッド t = 新しいスレッド (解析); t.Start(これ); // t.Start() の代わりに

[...] }

于 2012-06-14T18:38:19.520 に答える
0

静的メソッドとメンバー メソッド

  1. メンバー(非静的)メソッドがあり、それを呼び出すか
obj.SomeMethod();
  1. または、静的メソッドがあり、それを呼び出す
ClassName.SomeMethod();

定義クラス自体の内部で呼び出されない限り。次に、単に呼び出すことができます

SomeMethod();

両方の場合において。


ねじ切り

UI との対話 (たとえばbutton1.Text) が許可されている唯一のスレッドは、UI スレッド自体です。UI スレッドは、コードが通常実行されるメイン スレッドです。

C# で別のスレッドから GUI を更新する方法を参照してください。別のスレッドからフォームと対話するため。

于 2012-06-14T18:42:12.720 に答える
-3

終了を呼び出すには、フォーム クラスのインスタンスを作成してからメソッドを呼び出します。

Form1 frm1 = new Form1();
frm1.finished();
于 2012-06-14T18:33:19.530 に答える