【问题标题】:passing parameters to a thread将参数传递给线程
【发布时间】:2011-02-18 06:07:55
【问题描述】:

我想将一个带有参数的函数传递给 C# 中的 ThreadStart 构造函数。但是,这似乎是不可能的,因为我得到一个语法错误,所以我尝试做这样的事情

Thread t1 = new Thread(new ThreadStart(func1(obj1));

其中 obj1 是 List<string> 类型的对象(比如说)。

如果我想让一个线程执行这个以对象为参数的函数,并且我计划同时创建 2 个具有不同参数值的此类线程,那么实现此目的的最佳方法是什么?

【问题讨论】:

  • 您使用的是什么版本的 .NET?
  • 哇!我之前通过创建一个类来包含线程将使用的数据来做到这一点,但我不知道有这么多不同的方法可以给这种动物剥皮!

标签: c# multithreading


【解决方案1】:

如果您使用的是 .NET 3.5 或更高版本,一种选择是为此使用 lambda:

var myThread = new System.Threading.Thread(() => func1(obj1)); 

【讨论】:

    【解决方案2】:

    您需要ParametrizedThreadStart 将参数传递给线程。

    Thread t1 = new Thread(new ParametrizedThreadStart(func1);
    t1.Start(obj1);
    

    【讨论】:

    • 非常感谢.. 这个方法有效.. 但是,在这种情况下 func1 的定义必须是 void func1(object state) 并且不能是 void func1(List obj1) 为什么是这样吗?
    • ParametrizedThreadStart 委托类型就是这样定义的。您必须将object 转换回List<string> 内的func1
    【解决方案3】:

    你可以像这样开始一个新线程:

    Thread thread = new Thread(delegate() {
        // Code here.
    });
    thread.Start();
    

    anonymous method 中,您可以访问创建委托时范围内的变量。

    【讨论】:

      【解决方案4】:

      试试这个:

      var bar = 0.0;
      Thread t = new Thread(() => 
          {
              Foo(bar);
          });
      t.IsBackground = true;
      t.Start();
      

      或者在你的情况下:

      Object obj1 = new Object();
      Thread t = new Thread(() => 
          {
              func1(obj1);
          });
      t.IsBackground = true;
      t.Start();
      

      【讨论】:

        【解决方案5】:

        这就是你想要的效果吗?

                static void Main(string[] args)
            {
                var list = new List<string>(){
                    "a","b","c"
                };
        
                Thread t1 = new Thread(new ParameterizedThreadStart(DoWork));
        
                t1.Start(list);
        
                Console.ReadLine();
        
            }
        
            public static void DoWork(object stuff)
            {
                foreach (var item in stuff as List<string>)
                {
                    Console.WriteLine(item);
                }
            }
        

        【讨论】:

          【解决方案6】:

          Edit Assassin 无法让此代码正常工作,因此我在本文末尾提供了一个完整的控制台应用示例。

          { // some code Thread t1 = new Thread(MyThreadStart); t1.Start(theList); } void MyThreadStart(object state) { List<string> theList = (List<string>)state; //.. }

          这是我的编辑:下面是一个完整的控制台应用程序——该技术确实有效:

          using System; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { System.Threading.Thread t = new System.Threading.Thread(MyThreadStart); t.Start("Hello"); System.Console.ReadLine(); } static void MyThreadStart(object state) { System.Console.WriteLine((string)state); } } }

          【讨论】:

          • 这不起作用..我试过了... Thomas 建议的 ParametrizedThreadStart 方法有效。
          • @assassin 我向你保证,它确实有效。我已编辑我的条目以包含一个控制台应用程序,您可以将其直接粘贴到 Visual Studio 中并运行。此语法自 .Net 2.0 起就有效,如果您将“new Thread(MyThreadStart)”替换为“new Thread(new delegate
          【解决方案7】:
          static void func1(object parameter)
          {
             // Do stuff here.
          }
          
          static void Main(string[] args)
          {
            List<string> obj1 = new List<string>();
            Thread t1 = new Thread(func1);
            t1.Start(obj1);
          }
          

          它在 .Net 2.0 中使用了一个名为 ParameterizedThreadStart 的新委托。你可以阅读它here

          【讨论】:

            【解决方案8】:

            【讨论】:

              【解决方案9】:

              您绝对需要使用Thread 对象吗?或者您只是在寻找多线程处理?更“现代”的方法是使用异步委托:

              private delegate void FuncDelegate(object obj1);
              .
              .
              .
              FuncDelegate func = func1;
              IAsyncResult result = func.BeginInvoke(obj1, Completed, func);
              
              // do other stuff
              .
              .
              .
              
              private void Completed(IAsyncResult result)
              {
                  ((FuncDelegate)result.AsyncState).EndInvoke(result);
              
                  // do other cleanup
              }
              

              更“现代”的方法是在 .NET 4 TPL 中使用 Tasks

              【讨论】:

                猜你喜欢
                • 2015-03-08
                • 2014-01-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-06-25
                • 2010-10-26
                相关资源
                最近更新 更多