使用背景工人 - 更新上递归方法
进度的进度条下面是我想一艘进入后台工作的方法,但我怎么挣扎基于如何创建我的方法去做。正如你所能做的那样,它不会返回任何可以使用的东西,但是每次它被调用时,它都需要一个directoryInfo对象。使用背景工人 - 更新上递归方法
private void getSizeForTargetDirectory(DirectoryInfo dtar)
{
// generate a collection of objects. files comes first and then directories.
foreach (Object item in collection)
{
if (item == file)
{
track the size of the files as you encounter.
}
else if (item == directory)
{
// found a new directory, recall the method. !!!
}
}
}
这是用我的第一次后台工作,所以我有点卡住,我试图实现得益于这里找到帮助的东西,但是当我意识到我的方法是递归卡住了。
How do I display progress during a busy loop?
我实现了一个的doWork事件处理方法,但注意到,我需要,如果我有更多的文件和文件夹处理上下级子水平以某种方式召回方法。
我有一个简单的按钮单击事件处理程序调用我的'getSizeForTargetDirectory()方法时,当前选择的节点是一个目录。
private void retrieveInfoButton_Click(object sender, EventArgs e)
{
// check to see if the path is valid
// reset the labels and textfields.
string fullPath = treeDrives.SelectedNode.FullPath;
string sNodesName = treeDrives.SelectedNode.Text;
if (directory) // Enter here if its a directory.
{
string parentPath = treeDrives.SelectedNode.Parent.FullPath;
DirectoryInfo[] dirArray = populateFoldersArray(parentPath);
for (int i = 0; i < dirArray.Length; i++)
{
if (dirArray[i].Name == sNodesName)
{
getSizeForTargetDirectory(dirArray[i]);
// do work !
希望这可以解释我在做什么以及我如何做。问题是当我尝试发送的大部分工作来自递归方法时,如何使用后台工作者类的报告进度功能。
通过早期测试中,我发现我的getSize方法是一些调整后,难以置信的高效率和报告的大小信息对当前提供的文件夹非常quickley但后来我又用一个相当强大的开发机所以这可能不是对所有用户真正。
感谢您的阅读,希望有人能帮助!!!
我觉得这是很简单的使用在任Directory
或DirectoryInfo
内置的方法来获取所有的目录或文件,使用递归搜索选项:
public partial class Form1 : Form
{
private Action<float> updateProgMethod;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
updateProgMethod = UpdateProgress;
}
private void GetDirectorySizeAsync(string path)
{
backgroundWorker.RunWorkerAsync(path);
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
DirectoryInfo di = new DirectoryInfo((string)e.Argument);
di.GetTotalSize(ProgressCallback);
}
// Takes callbacks from the GetTotalSize() method
private void ProgressCallback(float p)
{
// Invokes update progress bar on GUI thread:
this.BeginInvoke(updateProgMethod, new object[] { p });
}
// Actually updates the progress bar:
private void UpdateProgress(float p)
{
progressBar.Value = (int)(p * (progressBar.Maximum - progressBar.Minimum)) + progressBar.Minimum;
}
}
public static class IOExtensions
{
public static long GetTotalSize(this DirectoryInfo directory, Action<float> progressCallback)
{
FileInfo[] files = directory.GetFiles("*.*", SearchOption.AllDirectories);
long sum = 0;
int countDown = 0;
for (int i = 0; i < files.Length; i++)
{
sum += files[i].Length;
countDown--;
if (progressCallback != null && countDown <= 0)
{
countDown = 100;
progressCallback((float)i/files.Length);
}
}
return sum;
}
}
很难猜测进步不知道第一个文件或文件夹的数量!
编辑:我改进了一点代码。
如果当你调用一个方法时,你不知道该方法需要多长时间,或者涉及多少个离散步骤,那么在方法是的时候没有办法显示进度条执行。
在我看来,一个进度条的目的是不给当任务即将完成有关的可靠信息。相反,其目的是防止用户因为他们认为你的程序被锁定而根本没有做任何事情而吓跑并取消整个操作。
既然你通过目录和子目录迭代,这里一个简单的方法可能是只是显示在标签上的当前目录。这会让用户放松地感觉事情正在发生,并且如果目录全部按字母顺序排列,他们甚至可以衡量自己整个操作过程。
不要忘了添加一个很酷的棘爪的东西! – Pondidum 2009-08-26 14:04:27
@Andy:我一直很喜欢Netscape曾经做过的事情 - 他们有一个进度条向右前进,当它到达时,它反转并向左前进,等等。 – MusiGenesis 2009-08-26 14:10:10
这使得很多感觉我对C#编码还很陌生,所以第一个回复让我有点害怕。虽然我喜欢更新简单标签的想法。突然间想到了很多选择。 TY – IbrarMumtaz 2009-08-26 18:19:02
我就举报你有多远得到,因为你不知道的目标,直到你到达那里。我会在每次调用时执行一次。也许到目前为止看到的#个文件和#个目录。
我原来的方法确实跟踪目前看到的文件和目录的数量......报告我得到多远似乎是一个相当可观的探索途径。 TIA – IbrarMumtaz 2009-08-26 18:20:52
你好塞西尔...... 问题? 这是一个有趣的代码...这是否意味着从给定directoryInfo对象我可以使用搜索选项来返回给定目录下的所有文件?无论是哪种情况,Ii都必须尝试一下,因为这会改变一切! – IbrarMumtaz 2009-08-27 11:37:18
是的。如果你想枚举每一个文件,它不会增加运行时间。 – 2009-08-27 13:49:48
非常有帮助。在WPF MVVM中实现并且工作得很好。 – 2012-05-29 05:18:49