2012-11-14 155 views
1

我需要將信息從掃描數據線程傳遞到記錄信息線程(寫入xml文件)。 它應該看起來是這樣的:線程交互(從一個線程到另一個線程的數據)c#

Application.Run() - 完整

掃描線 - 完整

寫入XLM線程 - ???

UI更新線程 - 我想我做到了

什麼,我現在得到:

 private void StartButtonClick(object sender, EventArgs e) 
    { 
     if (FolderPathTextBox.Text == String.Empty || !Directory.Exists(FolderPathTextBox.Text)) return; 
     { 
      var nodeDrive = new TreeNode(FolderPathTextBox.Text); 
      FolderCatalogTreeView.Nodes.Add(nodeDrive); 
      nodeDrive.Expand(); 
      var t1 = new Thread(() => AddDirectories(nodeDrive)); 
      t1.Start(); 
     } 
    } 

    private void AddDirectories(TreeNode node) 
    { 
     string strPath = node.FullPath; 
     var dirInfo = new DirectoryInfo(strPath); 
     DirectoryInfo[] arrayDirInfo; 
     FileInfo[] arrayFileInfo; 

     try 
     { 
      arrayDirInfo = dirInfo.GetDirectories(); 
      arrayFileInfo = dirInfo.GetFiles(); 
     } 
     catch 
     { 

      return; 
     } 

     //Write data to xml file 
     foreach (FileInfo fileInfo in arrayFileInfo) 
     { 
      WriteXmlFolders(null, fileInfo); 
     } 
     foreach (DirectoryInfo directoryInfo in arrayDirInfo) 
     { 
      WriteXmlFolders(directoryInfo, null); 
     } 


     foreach (TreeNode nodeFil in arrayFileInfo.Select(file => new TreeNode(file.Name))) 
     { 
      FolderCatalogTreeView.Invoke(new ThreadStart(delegate { node.Nodes.Add(nodeFil); })); 
     } 

     foreach (TreeNode nodeDir in arrayDirInfo.Select(dir => new TreeNode(dir.Name))) 
     { 
      FolderCatalogTreeView.Invoke(new ThreadStart(delegate 
       {node.Nodes.Add(nodeDir); 
       })); 

      StatusLabel.BeginInvoke(new MethodInvoker(delegate 
       { 
    //UI update...some code here 
       })); 
      AddDirectories(nodeDir); 
     } 
    } 

     private void WriteXmlFolders(DirectoryInfo dir, FileInfo file) 
    {//writing information into the file...some code here} 

如何從AddDirectories傳遞數據(遞歸方法)線程WriteXmlFolders線程?

+1

什麼是你的問題? –

+0

http://stackoverflow.com/questions/334860/in-c-sharp-what-is-the-recommended-way-of-passing-data-between-2-threads –

+1

看看生產者消費者。 http://msdn.microsoft.com/en-us/library/dd267312.aspx http://msdn.microsoft.com/en-us/library/dd267312.aspx – Paparazzi

回答

1

這是一個通用機制,它是一個線程如何生成另一個線程所消耗的數據。無論採用什麼方法(閱讀:現成的課程),您都會使用內部原則保持不變。主要球員(注意,在System.Threading命名空間中可用的許多鎖類,可以使用,但這些是最適合這樣的場景:

AutoResetEvent - 這允許一個線程進入睡眠模式(不消耗資源)直到另一個線程將它喚醒爲止,'auto'部分意味着一旦線程喚醒,該類將被重置,以便下一個Wait()調用再次將其置於睡眠狀態,而不需要重置任何東西。 ReaderWriterLockSlim(如果您使用的是.NET 4,建議使用第二個) - 這允許只有一個線程鎖定寫入數據,但多個線程可以讀取數據。在這種情況下,只有一個閱讀線程,但如果有很多,這種方法不會有所不同。

// The mechanism for waking up the second thread once data is available 
AutoResetEvent _dataAvailable = new AutoResetEvent(); 

// The mechanism for making sure that the data object is not overwritten while it is being read. 
ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim(); 

// The object that contains the data (note that you might use a collection or something similar but anything works 
object _data = null; 

void FirstThread() 
{ 
    while (true) 
    { 
     // do something to calculate the data, but do not store it in _data 

     // create a lock so that the _data field can be safely updated. 
     _readWriteLock.EnterWriteLock(); 
     try 
     { 
      // assign the data (add into the collection etc.) 
      _data = ...; 

      // notify the other thread that data is available 
      _dataAvailable.Set(); 
     } 
     finally 
     { 
      // release the lock on data 
      _readWriteLock.ExitWriteLock(); 
     } 
    } 
} 

void SecondThread() 
{ 
    while (true) 
    { 
     object local; // this will hold the data received from the other thread 

     // wait for the other thread to provide data 
     _dataAvailable.Wait(); 

     // create a lock so that the _data field can be safely read 
     _readWriteLock.EnterReadLock(); 
     try 
     { 
      // read the data (add into the collection etc.) 
      local = _data.Read(); 
     } 
     finally 
     { 
      // release the lock on data 
      _readWriteLock.ExitReadLock(); 
     } 

     // now do something with the data 
    } 
} 

在.NET 4中有可能避免使用ReadWriteLock和使用併發安全的集合,如ConcurrentQueue這將在內部確保讀/寫是線程安全的一個。儘管如此,仍然需要AutoResetEvent

.NET 4提供了一種機制,可以用來避免甚至需要AutoResetEvent - BlockingCollection - 該類提供了線程休眠狀態直到數據可用的方法。 MSDN page包含有關如何使用它的示例代碼。

相關問題