我需要将信息从扫描数据的线程传递到记录信息线程(写入xml文件)。它应该看起来像这样:
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线程?
发布于 2012-11-15 04:04:18
下面是一个线程如何生成另一个线程使用的数据的通用机制。无论您使用哪种方法(即:现成的类),内部原则都保持不变。主要的参与者是(请注意,在System.Threading命名空间中有许多可用的锁定类,但这些类最适合此场景:
AutoResetEvent -这允许线程进入睡眠模式(不消耗资源),直到另一个线程将其唤醒。“自动”部分意味着一旦线程唤醒,类就会被重置,因此下一次Wait()调用将再次将其置于休眠状态,而无需重置任何内容。
ReaderWriterLock或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包含有关如何使用它的示例代码。
发布于 2012-11-15 04:52:21
以防你用它作为答案
看一看生产者和消费者。
BlockingCollection Class
How to: Implement Various Producer-Consumer Patterns
https://stackoverflow.com/questions/13385509
复制相似问题