【问题标题】:How to Pass a variable to another Thread如何将变量传递给另一个线程
【发布时间】:2011-04-27 12:52:15
【问题描述】:
using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Taking data from Main Thread\n->");
        string message = Console.ReadLine();

        ThreadStart newThread = new ThreadStart(delegate { Write(message); });

        Thread myThread = new Thread(newThread);

    }

    public static void Write(string msg)
    {
        Console.WriteLine(msg);
        Console.Read();
    }
}
}

【问题讨论】:

  • 大声笑,'猜猜问题'
  • 好吧,message 变量已经被传递给Write 方法(它将在另一个线程上执行)所以你还想要什么?
  • 我认为这就是答案。这就像危险。
  • 哎呀。我说我做错了。因为我忘记启动线程。哈哈 菜鸟

标签: c# multithreading arguments


【解决方案1】:

如果您有一些数据想要通过调用序列“流动”一些数据,您也可以使用CallContextHere is a good blog posting about LogicalCallContext from Jeff Richter.

using System;  
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 

namespace ConsoleApplication1 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
        Console.WriteLine("Taking data from Main Thread\n->"); 
        string message = Console.ReadLine(); 

        //Put something into the CallContext
        CallContext.LogicalSetData("time", DateTime.Now);

        ThreadStart newThread = new ThreadStart(delegate { Write(message); }); 

        Thread myThread = new Thread(newThread); 

    } 

    public static void Write(string msg) 
    { 
        Console.WriteLine(msg); 
        //Get it back out of the CallContext
        Console.WriteLine(CallContext.LogicalGetData("time"));
        Console.Read(); 
    } 
  } 
} 

【讨论】:

    【解决方案2】:

    Thread.Start 有一个重载,可让您传入参数。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Taking data from Main Thread\n->");
            string message = Console.ReadLine();  
    
            Thread myThread = new Thread(Write);
            myThread.Start(message);
    
        }
    
        public static void Write(object obj)
        {
            string msg = (string)obj;
            Console.WriteLine(msg);
            Console.Read();
        }
    }
    

    【讨论】:

      【解决方案3】:

      获得将变量传递给线程的相同效果的一种方法是创建一个您希望传递给线程的类型的类范围的私有数据成员。在启动线程之前将此值设置为您想要的任何值。如果您有许多线程,则需要锁定该类范围的数据成员以防止出现意外值。或者,您可以使用 .NET 原生 Mutex 功能来控制对变量的访问。

      例如(没有测试这个,只是即时写出来的):

      using System;
      
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading;
      
      namespace ConsoleApplication1
      {
      class Program
      {
          private string threadVariable;
      
          static void Main(string[] args)
          {
              Console.WriteLine("Taking data from Main Thread\n->");
              string message = Console.ReadLine();
      
              threadVariable = "stuff";
      
              Thread myThread = new Thread(Write);
              Thread.IsBackground = true;
              Thread.Start();
          }
      
          public static void Write()
          {
              Console.WriteLine(stuff);
              Console.Read();
          }
      }
      }
      

      【讨论】:

        【解决方案4】:

        如果你问如何将参数传递给线程,请参考:

        http://www.yoda.arachsys.com/csharp/threads/parameters.shtml

        【讨论】:

          【解决方案5】:

          我不确定我是否正确理解了您的问题,但以下 MSDN 文章展示了如何以您正在执行的方式(即通过 ThreadStart 和委托)将数据传递给线程:

          Passing data to thread

          using System;
          using System.Threading;
          
          class Test
          {
              static void Main() 
              {
                  // To start a thread using a static thread procedure, use the
                  // class name and method name when you create the ThreadStart
                  // delegate. Beginning in version 2.0 of the .NET Framework,
                  // it is not necessary to create a delegate explicitly. 
                  // Specify the name of the method in the Thread constructor, 
                  // and the compiler selects the correct delegate. For example:
                  //
                  // Thread newThread = new Thread(Work.DoWork);
                  //
                  ThreadStart threadDelegate = new ThreadStart(Work.DoWork);
                  Thread newThread = new Thread(threadDelegate);
                  newThread.Start();
          
                  // To start a thread using an instance method for the thread 
                  // procedure, use the instance variable and method name when 
                  // you create the ThreadStart delegate. Beginning in version
                  // 2.0 of the .NET Framework, the explicit delegate is not
                  // required.
                  //
                  Work w = new Work();
                  w.Data = 42;
                  threadDelegate = new ThreadStart(w.DoMoreWork);
                  newThread = new Thread(threadDelegate);
                  newThread.Start();
              }
          }
          
          class Work 
          {
              public static void DoWork() 
              {
                  Console.WriteLine("Static thread procedure."); 
              }
              public int Data;
              public void DoMoreWork() 
              {
                  Console.WriteLine("Instance thread procedure. Data={0}", Data); 
              }
          }
          

          【讨论】:

            【解决方案6】:

            我使用一个单独的工作类并在构造函数中填充一个成员变量,然后我使用一个 void 方法作为使用私有成员变量的委托:

            using System;
            
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Threading;
            
            namespace ConsoleApplication1
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        Console.WriteLine("Taking data from Main Thread\n->");
                        string message = Console.ReadLine();
                        WorkerClass workerClass = new WorkerClass(message);
            
                        ThreadStart newThread = new ThreadStart(workerClass.DoWork);
            
                        Thread myThread = new Thread(newThread);
                        myThread.Start();
                        Console.Read();
            
                    }
            
            
                }
            
                internal class WorkerClass
                {
                    private string _workerVariable = "";
            
                    internal WorkerClass(string workerVariable)
                    {
                        _workerVariable = workerVariable;
                    }
            
                    internal void DoWork()
                    {
                        Console.WriteLine(_workerVariable);
                    }
                }
            
            }
            

            【讨论】:

              【解决方案7】:

              我在 vb2005 中编写的一组方便的类将允许轻松创建具有一到四个绑定参数和零或一个未绑定参数的委托。大量的复制/粘贴代码,因为 .net 不支持可变参数泛型,但可以创建一个 MethodInvoker,它会通过说 (vb.net 语法来调用 foo(bar,boz),但方法在C#):

              theMethodInvoker = InvMaker.NewInv(地址的 foo, bar, boz) theMethodInvoker() ' 调用 foo(bar,boz)

              这将生成一个对象,其中包含字段 Param1 作为 BarType,Param2 作为 BozType,以及作为 Action(of BarType, BozType) 的 theAction。它将这些字段设置为 bar、boz 和 foo,并返回一个调用 doIt 的 MethodInvoker,一个调用 theAction(Param1, Param2) 的方法。如果我需要一个 Action(of Integer),我会使用:

              theMethodInvoker = ActionMaker(integer).NewInv(addressof foo, bar, boz) theMethodInvoker(9) ' 调用 foo(9,bar,boz)

              真的很漂亮。 Lambdas 避免了对剪切和粘贴库的需要,但它们的内部实现是相似的。我读过 Lambda 会导致编辑和继续的困难;我知道我的方法不行。

              【讨论】:

                猜你喜欢
                • 2021-09-28
                • 1970-01-01
                • 1970-01-01
                • 2019-05-02
                • 1970-01-01
                • 1970-01-01
                • 2019-02-01
                • 2015-06-28
                • 1970-01-01
                相关资源
                最近更新 更多