.NET - 有没有办法创建非静态线程方法?

ala*_*a27 5 .net c# multithreading

有没有办法在.NET上创建一个非静态线程方法?请给我看代码.

以下代码不起作用:

ThreadStart ts = delegate { drawFloorAround(); };
public void drawFloorAround()
{
            ...
}

给出此错误 - >"字段初始值设定项不能引用非静态字段,方法或属性".如果我改变方法做静态,它的工作原理.但我不想.

Eri*_*ert 10

...给出此错误"字段初始值设定项不能引用非静态字段,方法或属性".

请仔细阅读错误消息.它告诉你究竟出了什么问题.甲字段初始不能引用非静态方法.那是因为编译器试图保护您免受此错误的影响:

class C
{
    int foo;
    int bar = GetBar();
    public C(int newFoo)
    {
        this.foo = newFoo;
    }
    private int GetBar() { return this.foo + 1; }
}
Run Code Online (Sandbox Code Playgroud)

你做"新C(123)".什么是酒吧?如果这是合法代码,则将其设置为1,而不是124.为什么?因为第一个foo初始化为零,然后调用GetBar(),然后构造函数体将this.foo设置为123.

为了防止此错误,在字段初始值设定项中引用实例方法或字段是非法的.

现在,您可以合理地指出,在您的代码中,您不使用实例方法,您只需引用它.你从来没有真正称呼它.这实际上是安全的.但是,C#的规则设计简单而保守; 即使我们可以证明这种情况下是安全的,我们采取保守的,简单的路径,并说,任何一个领域的初始参考实例是非法的.

如果我将方法更改为静态,它可以工作.

正确.在这种情况下,该方法不依赖于尚未建立的实例状态.

但我不想.

好的,那么你唯一的另一个选择是停止使用字段初始化程序.将初始化放在构造函数中; 然后,您负责确保初始化不会意外使用未初始化状态.


Mar*_*ers 8

如果你的意思是可以使用非静态方法启动线程 - 即实例方法 - 那么是的.但是同样的规则适用于直接调用实例方法 - 只有拥有实例才能执行.例如,如果在变量中有一个实例,foo则可以这样写:

ThreadStart ts = delegate { foo.DrawFloorAround(); };
Run Code Online (Sandbox Code Playgroud)

如果您还没有可以使用的实例,则必须先创建一个:

ThreadStart ts = delegate { new Foo().DrawFloorAround(); };
Run Code Online (Sandbox Code Playgroud)

如果您不想创建实例,那么您的方法可能应该是静态的.


Ali*_*tad 5

    public class DoSomthing
    {

        public void Do()
        {
            Thread t = new Thread(DoInBackground);
            t.Start();
        }

        public void DoInBackground()
        {
            // ....
        }

    }
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 3

编辑:示例代码中的问题是它是一个字段初始化程序。将此代码移至显式构造函数:

ThreadStart ts;
public TypeName() {//constructor
    ts = this.SomeMethod;
}
private void SomeMethod() {....}
Run Code Online (Sandbox Code Playgroud)

任何方法都可以充当 ThreadStart 作为日志,它不接受参数并返回 void。IMO 最简单的选择是 lambda 或 anon 方法,因为这允许闭包:

ThreadStart ts = delegate {
    someObj.DoSomething(x, y, "z");
};
Run Code Online (Sandbox Code Playgroud)

但对于返回 void 且不带参数的实例方法:

var obj = /* init obj */
ThreadStart ts = obj.SomeMethod;
Run Code Online (Sandbox Code Playgroud)

然后

var thread = new Thread(ts);
Run Code Online (Sandbox Code Playgroud)