启动线程时如何将参数传递给方法? [复制]
Posted
技术标签:
【中文标题】启动线程时如何将参数传递给方法? [复制]【英文标题】:How can I pass a parameter to a method when I start a thread? [duplicate] 【发布时间】:2021-10-18 00:58:01 【问题描述】:我想在线程中启动方法时将参数传递给方法。
例如,我还想在 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] 作为参数。
【问题讨论】:
新线程((obj) => Method2(list[(int)obj)).Start(k); 或者... new Thread((obj) => Method2((string)obj)).Start(list[k]); 我认为问题在于变量 k 是线程之间共享的。试试foreach( int k in Enumerable.Range( 0, 3 ) )
为什么要特别使用线程而不是任务?
您是否有意“设置并忘记”您创建的每个Thread
?
【参考方案1】:
我认为解决此问题的更好方法是使用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
的另一种解决方案,但这次你await
为每个Task
完成。
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 );
如果您不喜欢这样并想坚持使用您的解决方案,那么您可以在 for
循环中本地捕获 i
变量。
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
、1
、2
。
现在,运行这段代码(注意我删除了Thread.Sleep
:
static void Main( string[ ] _ )
for ( int i = 0; i < 3; i++ )
new Thread( ( ) => Console.WriteLine( $"i" ) ).Start( );
Console.ReadLine( );
您应该看到打印到控制台的值,3
、3
、3
。
【讨论】:
Each invocation of Method2 will be done is a separate thread.
不是 100% 正确的。以上是关于启动线程时如何将参数传递给方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何将传递给我的 bash 脚本的所有参数传递给我的函数? [复制]