C#中的多线程:如何将函数名称传递给另一个函数来启动新线程?

时间:2009-02-18 09:05:47

标签: c# .net multithreading oop

我在C#代码中使用多线程如下:

Thread startThread;

public void NewThread()
{
   ThreadStart starter = delegate { foo(); };
   startThread = new Thread(starter);
   startThread.Start();
}

private void foo()
{
   //do some work
}

然后在我的应用程序中,我调用NewThread()来运行新线程。

但是现在我在每个类上都有很多线程,并且每个类都有一个NewThread(),我想把它移动到一个静态的Util类,并在每次我想要一个新线程时将它传递给它。那个功能。

你知道这是如何做到这一点的最佳方式,如果是的话我怎样才能将函数名称作为参数传递给它?

6 个答案:

答案 0 :(得分:4)

好吧,由于该方法是私有的,调用者知道方法名称是否有意义?如果它是公开的,您可以传递方法:

public void NewThread(Action task)
{
   ThreadStart starter = delegate { task(); };
   startThread = new Thread(starter);
   startThread.Name = task.Method.Name;
   startSpoolerThread.Start();
}

public void foo()
{
   //do some work
}

NewThread(obj.foo);

但是,对于私有方法,我怀疑枚举/开关是最好的选择......

NewThread(TasktType.Foo);

或者,您可以通过反思获得该方法......

public void NewThread(string name)
{
    MethodInfo method = GetType().GetMethod(name,
        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
        null, Type.EmptyTypes, null);
    ThreadStart starter = delegate { method.Invoke(this, null); };
    // etc (note: no point using Delegate.CreateDelegate for a 1-call usage

答案 1 :(得分:3)

除非您明确创建线程的具体原因,为什么不使用Threadpool? Threadpool.QueueUserWorkItem方法将委托作为要执行的工作单元。委托是一种特定类型,但您可以像在示例中一样将自己的委托调用包装在其中。除非您需要精细控制或取消,否则通常最好使用线程池而不是自己旋转线程。

答案 2 :(得分:1)

我建议您考虑查看并行扩展任务API的CTP;你没有提到为什么你需要一个线程,但他们已经自动化了大部分here's a link to their blog

答案 3 :(得分:0)

请查看以下有关Codeproject“Poor Man's Parallel.ForEach Iterator”的文章。我认为这正是你在寻找的东西。非常容易使用。

对于更强大的内容,请查看Power Threading Library

答案 4 :(得分:0)

或者,如果您正在使用Win.Forms或类似的基于GUI的应用程序,我建议使用BackgroundWorker。它负责为大多数与线程相关的事件进行编组,并且中止也很简单(如果这是你需要做的事情)。

答案 5 :(得分:0)

代理已经提供了一种异步执行它们的方法。例如:

delegate void dowork();
private static void WorkDone(IAsyncResult result)
{
   ((dowork)result.AsyncState).EndInvoke(result);
    // this function is called when the delegate completes
}
public void Start()
{
    dowork dw = delegate {// code in this block has it's own thread };
    dw.BeginInvoke(WorkDone, null);
}

因此,为了将函数指针传递给其他任何东西,您只需要创建一个具有正确签名的委托(在本例中我使用了匿名方法,但您可以使用具有正确签名的任何函数)并将其称为BeginInvoke方法,传递一个将在完成时调用的函数..该函数必须在原始委托上调用EndInvoke,并将其传递给result参数中的WorkDone函数。