首页 > 解决方案 > 启动线程时如何将参数传递给方法?

问题描述

我想在线程中启动方法时将参数传递给方法。

例如,我还想在 k=0 直到 k=10 的 for 循环的上下文中执行此操作。

此外,我希望每个线程彼此独立。到目前为止,我有这个:

for (int k = 0; k < 3; k++)
{
new Thread(() => Method2(list[k])).Start();
}

其中Method2应该做一些处理,定义如下(body不重要,它基本上是创建并写入文件):

public static void Method2(string SYM)

不知何故,当我运行代码时,我确实创建了三个线程,但传递给每个线程的参数似乎只是所有三个线程的 list[2] 参数。我希望每个线程都有 list[0] list[1] list[3] 作为参数。

标签: c#multithreading

解决方案


我认为解决此问题的更好方法是使用Parallel.ForEach.

static void Main( string[ ] _ )
{
    var list = new List<string> { "Value1", "Value2", "Value3" };
    Parallel.ForEach( list, value => Method2( value ) );
}

这是另一个使用Task's(设置和遗忘)的解决方案。

static void Main( string[ ] _ )
{
    var list = new List<string> { "Value1", "Value2", "Value3" };            
    for ( int i = 0; i < list.Count; i++ )
    {
        var index = i;
        // Set and forget.
        Task.Run( ( ) => Method2( list[ index ] ) );                                
    }
}

这是另一个使用Task's 的解决方案,但这次你await要完成每个Task's。

static async Task Main( string[ ] _ )
{
    var list = new List<string> { "Value1", "Value2", "Value3" };
    var tasks = new List<Task>( list.Count );
    for ( int i = 0; i < list.Count; i++ )
    {
        var index = i;
        // Set and forget.
        tasks.Add( Task.Run( ( ) => Method2( list[ index ] ) ) ); 
    }

    await Task.WhenAll( tasks );
}

如果您不喜欢这样并想坚持使用您的解决方案,那么您可以在循环中i本地捕获变量。for

for ( int i = 0; i < list.Count; i++ )
{
    var index = i;
    new Thread( ( ) => Method2( list[ index ] ) ).Start( );
}

每个Thread人都有自己的index变量副本,而不是每个人都Thread共享对i变量的引用(这是您当前正在做的事情)。

您的for循环在第一个循环Thread开始之前完成;因此,当其中一个Thread' 最终启动时,它会看到i设置为(在您的情况下3)的最后一个值。

如果您不相信我,请运行以下代码。

static void Main( string[ ] _ )
{       
    for ( int i = 0; i < 3; i++ )
    {
        new Thread( ( ) => Console.WriteLine( $"{i}" ) ).Start( );
        Thread.Sleep( 1500 );
    }            
    Console.ReadLine( );
 }

应该会看到打印到控制台的值0, 。现在,运行这段代码(并注意我删除了:12Thread.Sleep

static void Main( string[ ] _ )
{       
    for ( int i = 0; i < 3; i++ )
    {
        new Thread( ( ) => Console.WriteLine( $"{i}" ) ).Start( );
    }            
    Console.ReadLine( );
}

应该会看到打印到控制台的值3, 。33


推荐阅读