简体   繁体   English

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

[英]Multithreading in C#: How can I pass a function name to another function to start a new thread?

I am using multithreading in my C# code as follow: 我在我的C#代码中使用多线程如下:

Thread startThread;

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

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

And then in my application I call NewThread()to run the new thread. 然后在我的应用程序中,我调用NewThread()来运行新线程。

But now I am having lots of threads on each class and each one has a NewThread() for itself, I was thinking of moving this to a static Util class and pass it the function name each time I want a new thread on that function. 但是现在我在每个类上都有很多线程,并且每个类都有一个NewThread(),我想把它移动到一个静态的Util类,并在每次我希望在该函数上有一个新线程时将它传递给它。

Do you know how this the best way of doing it, if yes how can I pass the function name as a parameter to it? 你知道这是怎样做的最佳方法,如果是的话我怎样才能将函数名称作为参数传递给它?

Well, since the method is private, does it make sense for the caller to know the method name? 好吧,由于该方法是私有的,调用者知道方法名称是否有意义? If it was public, you could pass the method in: 如果它是公开的,您可以传递方法:

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);

However, for a private method, I suspect an enum/switch is the best option... 但是,对于私有方法,我怀疑枚举/开关是最好的选择......

NewThread(TasktType.Foo);

Alternatively, you can get the method via reflection... 或者,你可以通过反思获得方法......

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

Unless there's a specific reason you're explicitly creating threads, why not use the Threadpool? 除非有明确创建线程的特定原因,否则为什么不使用Threadpool? The Threadpool.QueueUserWorkItem method takes a delegate as the unit of work to perform. Threadpool.QueueUserWorkItem方法将委托作为要执行的工作单元。 The delegate is a specific type but you can wrap your own delegate call within it as you do in your example. 委托是一种特定类型,但您可以像在示例中一样将自己的委托调用包装在其中。 Unless you need fine control or cancellation, in general it's better to use the thread pool rather than spinning up threads yourself. 除非您需要精细控制或取消,否则通常最好使用线程池而不是自己旋转线程。

I'd encourage you to also consider looking at the CTP of Parallel Extensions Task APIs; 我建议您考虑查看并行扩展任务API的CTP; you don't mention why you need a thread, but they've automated much of this here's a link to their blog 你没有提到为什么你需要一个主题,但他们已经自动化了大部分内容,这是他们博客的链接

Take a look at the following article on Codeproject " Poor Man's Parallel.ForEach Iterator ". 看看下面有关Codeproject“ 穷人的Parallel.ForEach Iterator ”的文章。 I think that's exactly what you are searching for. 我认为这正是你在寻找的东西。 Very easy to use. 非常好用。

For something more powerful also take a look at Power Threading Library . 对于更强大的东西,还可以看一下Power Threading Library

Alternatively, if you are doing a Win.Forms or similar GUI-based application I'd recommend using BackgroundWorker . 或者,如果您正在使用Win.Forms或类似的基于GUI的应用程序,我建议使用BackgroundWorker It takes care of marshalling for most thread-related events for you and is also much less complex to abort (if that is something you need to do). 它负责为大多数与线程相关的事件进行编组,并且中止(如果这是你需要做的事情)也不那么复杂。

Delegates already provide a method to execute them asynchronously. 代理已经提供了一种异步执行它们的方法。 For example: 例如:

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);
}

So in order to pass a function pointer to anything else, you need only create a delegate with the correct signature (in this case I used an anonymous method, but you can use any function with the correct signature) and call it's BeginInvoke method, passing a function that will get called when it's done.. that function has to then call EndInvoke on the original delegate, which is passed to the WorkDone function in the result parameter. 所以为了将函数指针传递给其他任何东西,你只需要创建一个具有正确签名的委托(在这种情况下我使用了匿名方法,但你可以使用任何具有正确签名的函数)并调用它的BeginInvoke方法,传递一个函数将在完成后被调用..该函数必须在原始委托上调用EndInvoke,并将其传递给result参数中的WorkDone函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM