C# C错误:非静态字段需要对象引用

C# C错误:非静态字段需要对象引用,c#,multithreading,visual-studio-2010,static,C#,Multithreading,Visual Studio 2010,Static,我有一个小小的windows窗体程序,可以使用console.beep从字符串播放音乐。我有一个字符串播放位,它基本上是一个for循环,一个字符一个字符地遍历字符串,并在一个新线程“t”中播放相应的音符。当您点击播放按钮时,线程开始,按钮变为停止按钮。如果您在播放音乐时按下此“立即停止”按钮,它将停止,并通过调用finished方法将按钮更改回播放状态。 我的问题是,我希望在新线程中运行的循环在循环已经运行并且歌曲结束时也调用finished方法。 但是,如果我在循环后放置finished,那么

我有一个小小的windows窗体程序,可以使用console.beep从字符串播放音乐。我有一个字符串播放位,它基本上是一个for循环,一个字符一个字符地遍历字符串,并在一个新线程“t”中播放相应的音符。当您点击播放按钮时,线程开始,按钮变为停止按钮。如果您在播放音乐时按下此“立即停止”按钮,它将停止,并通过调用finished方法将按钮更改回播放状态。 我的问题是,我希望在新线程中运行的循环在循环已经运行并且歌曲结束时也调用finished方法。 但是,如果我在循环后放置finished,那么非静态字段错误需要对象引用。如果我将finshed方法更改为static,那么更改按钮文本的位将不起作用

这是你按下按钮时的代码

//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解析方法是静态的吗?似乎您正在尝试从静态方法调用finished,而不提供实例,这就是为什么您要获取非静态字段错误所需的对象引用。

我认为这样做会更好。这样,您就可以在RunWorkerCompleted事件中调用finished方法。

要调用finished,请创建表单类的实例,然后调用该方法

Form1 frm1 = new Form1();
frm1.finished();

您需要做的是确保创建的线程可以访问创建它的对象,即在button1\u Click方法的范围内。为此,您可以调用t.Start而不是t.Start。这样做,您将向线程传递能够调用finished方法的对象。 接下来,您需要确保parse方法接受Object类型的参数。在这样做时,当您调用t.starttthis时,方法parse会将其作为参数接收。转换为适当的类型需要一个简单的强制转换。现在,当您希望歌曲在线程中停止时,只需调用casted参数上的finish方法。 因此,您的代码应该如下所示:

公共空对象解析 { MyClass c=o作为MyClass;//用类的名称替换MyClass

[...] // play music here

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

公共无效按钮1\u单击对象发送者,事件参数e { [……]

线程t=新线程解析; t、 starttthis;//而不是t.Start

[……] }

静态法与成员法 要么您有一个成员非静态方法并调用它 obj.somethod; 或者您有一个静态方法,并使用 ClassName.SomeMethod; 除非在定义类本身内部调用它。然后可以简单地用

SomeMethod();
在这两种情况下

穿线 唯一允许与UI交互的线程,例如与button1.Text交互的线程是UI线程本身。UI线程是代码正常运行的主线程


有关从另一个线程与表单交互的详细信息,请参阅。

您需要做的是在主线程上引发一个事件以调用已完成的方法。 首先在表单类中声明事件和委托

public delegate void CallFinishedEventHandler();
public event CallFinishedEventHandler CallFinished;
然后创建一个事件处理程序,在引发事件时调用它,并在中调用finished方法

void Form1_CallFinished()
{
  Finished();
}
然后在表单构造函数中将事件处理程序连接到事件

public Form1()
{
    CallFinished += Form1_CallFinished;
}
最后,在音乐播放代码中,当您希望在UI线程上调用finished方法时,请调用事件,以便在UI线程上激发它

this.Invoke(CallFinished);

这很简单,创建一个全局线程,然后在需要的地方访问它

Thread t;
    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.
                t = new Thread(parse); 
                t.Start();
                button1.Text = "Stop";
            }
            else 
            {
                finished();
            }
        }

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

-1:OP需要在同一个Form1实例上调用finished。完成后,我将其放在parse方法中for循环之后,它编译并运行时没有错误,但finished方法似乎没有被调用。按钮文本不变