2012-06-10 20 views
-2

如何以有效和受控的方式動態生成線程?線程將根據每個XML主機ID動態創建。使用C#.NET動態生成新線程

例子:

samplethread1 for hostid:-1 
samplethread2 for hostid:-2 

因爲我不能依靠主機ID數我需要讓我的代碼動態:建議我怎麼能有每個線程的控制。

拿到了一塊示例XML代碼:

<?xml version="1.0" standalone="yes"?> 
    <HOSTS> 
    <Host id = '1'> 
     <Extension>txt</Extension> 
     <FolderPath>C:/temp</FolderPath> 
    </Host> 
    <Host id = '2'> 
     <Extension>rar</Extension> 
     <FolderPath>C:/Sample</FolderPath> 
    </Host> 
    </HOSTS> 
+0

只是生成線程列表或數組,並添加新的線程。 –

回答

3

我不得不承認,這個問題還不是特別清楚。但是如果你正在爲每個主機創建一個新的線程,那麼這個怎麼樣?這是使用.NET 4.0 Task Parallel Library。從.NET 4.0開始,這是一個簡單的方法來利用處理器的併發功能。

static void Main(string[] args) 
{ 
    var currentDir = Directory.GetCurrentDirectory(); 
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml"))); 
    var taskFactory = new TaskFactory(); 

    foreach (XElement host in xDoc.Descendants("Host")) 
    { 
     var hostId = (int) host.Attribute("id"); 
     var extension = (string) host.Element("Extension"); 
     var folderPath = (string) host.Element("FolderPath"); 
     taskFactory.StartNew(() => DoWork(hostId, extension, folderPath)); 
    } 
    //Carry on with your other work 
} 

static void DoWork(int hostId, string extension, string folderPath) 
{ 
    //Do stuff here 
} 

如果您使用.NET 3.5或以前的,那麼你可以自己創建線程:

static void Main(string[] args) 
{ 
    var currentDir = Directory.GetCurrentDirectory(); 
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml"))); 
    var threads = new List<Thread>(); 

    foreach (XElement host in xDoc.Descendants("Host")) 
    { 
     var hostID = (int) host.Attribute("id"); 
     var extension = (string) host.Element("Extension"); 
     var folderPath = (string) host.Element("FolderPath"); 
     var thread = new Thread(DoWork) 
         { 
          Name = string.Format("samplethread{0}", hostID) 
         }; 
     thread.Start(new FileInfo 
         { 
          HostId = hostID, 
          Extension = extension, 
          FolderPath = folderPath 
         }); 
     threads.Add(thread); 
    } 
    //Carry on with your other work, then wait for worker threads 
    threads.ForEach(t => t.Join()); 
} 

static void DoWork(object threadState) 
{ 
    var fileInfo = threadState as FileInfo; 
    if (fileInfo != null) 
    { 
     //Do stuff here 
    } 
} 

class FileInfo 
{ 
    public int HostId { get; set; } 
    public string Extension { get; set; } 
    public string FolderPath { get; set; } 
} 

這對我來說仍然是the best guide to Threading

編輯

所以這是什麼,我認爲你是在您的評論獲得基於任務的版本?

static void Main() 
{ 
    var currentDir = Directory.GetCurrentDirectory(); 
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml"))); 
    var taskFactory = new TaskFactory(); 

    //I'm assuming this ID would normally be user input, or be passed from some other external source 
    int hostId = 2; 

    taskFactory.StartNew(() => DoWork(hostId, xDoc)); 
    //Carry on with your other work 
} 

static void DoWork(int hostId, XDocument hostDoc) 
{ 
    XElement foundHostElement = (from hostElement in hostDoc.Descendants("Host") 
            where (int)hostElement.Attribute("id") == hostId 
            select hostElement).First(); 
    var extension = (string)foundHostElement.Element("Extension"); 
    var folderPath = (string)foundHostElement.Element("FolderPath"); 
    //Do stuff here 
} 
+0

@micheal感謝您的回覆和簡單易懂的代碼,小小的澄清如何根據主機ID獲取dowork方法中的元素? – user1300588

+0

@ user1300588我不太確定你的意思?你只是想傳遞一個主機ID到DoWork方法,然後根據它找到其他元素(Extension&FolderPath)? – Michael

+0

@micheal謝謝你,是啊我的疑問是...現在它被這個帖子清除thanx很多 – user1300588

1

如果你不想保持陣列處理的你可以「射後不理」,所以我會建議使用「線程池」:

01:在 http://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx,如果你想創建你可以做一些像陣列

ThreadPool.QueueUserWorkItem(); 

更多信息創建和運行的線程

List<Thread> threads = new List<Thread>(); 
threads.Add(new Thread()); //Create the thread with your parameters here 

例如:http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx