2010-10-19 108 views
6
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(); 
    } 
} 
} 
+4

這裏有問題嗎? – Jonathan 2010-10-19 14:39:34

+1

哈哈,'猜猜問題問題' – 2010-10-19 14:40:31

+0

那麼,'message'變量已經被傳遞給了'Write'方法(它將在另一個線程上執行),那麼你還想要什麼? – 2010-10-19 14:41:45

回答

4

您也可以使用該CallContext如果你有想要「流」的一些數據的一些數據與您的通話順序。 Here 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(); 
    } 
    } 
} 
+0

CallContext.GetData(「time」)在線程內返回null。 – Rauhotz 2013-07-11 08:42:11

0

我不知道如果我正確地理解你的問題,但下面的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); 
    } 
} 
0

我使用一個單獨的工人階級,並在構造函數中填充的成員變量,然後我用一個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); 
     } 
    } 

} 
1

一種方式來獲得同樣的效果將一個變量傳遞給一個線程的方法是創建一個你希望傳遞給該線程的類的私有數據成員。在啓動線程之前將此值設置爲任何您想要的值。如果有很多線程,則需要對此類的數據成員加鎖以防止意外的值。或者你可以使用.NET本地互斥功能來控制對變量的訪問。

例如(沒有測試這一點,只是寫起來就飛):

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

一個方便的類集我VB2005寫了將允許輕鬆創建一個委託一至四個綁定參數和零個或一個未綁定的參數。一大堆的複製/粘貼代碼,因爲.net不支持可變泛型,但是可以創建一個MethodInvoker,它會通過說(vb.net語法)來調用foo(bar,boz),但是這種方法在C#):

 
    theMethodInvoker = InvMaker.NewInv(addressof foo, bar, boz) 
    theMethodInvoker() ' Calls foo(bar,boz) 

這將產生包含字段參數1爲杆型,參數2爲BozType的對象,並且作爲theAction行動(杆型的,BozType)。它會將這些字段設置爲bar,boz和foo,並返回一個稱爲doIt的MethodInvoker,該方法稱爲Action(參數1,參數2)。如果我需要動作(整數),我會用:

 
    theMethodInvoker = ActionMaker(of Integer).NewInv(addressof foo, bar, boz) 
    theMethodInvoker(9) ' Calls foo(9,bar,boz) 

真的很漂亮。 Lambdas避免了對剪切和粘貼庫的需求,但它們的內部實現類似。我讀過Lambdas導致編輯和繼續的困難;我知道我的方法沒有。

3

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(); 
    } 
} 
相關問題