两次启动相同的线程 - 第一次完成后第二次

时间:2014-09-02 11:51:40

标签: c# multithreading thread-safety

所以我创建了一个Thread,它执行一个依赖于全局变量的函数。之后,我想更改该变量并再次运行该线程,以便它再次使用另一个参数执行我的过程。问题是,我的线程完成时似乎无法弄清楚。经过大量的谷歌搜索,我发现没有什么可以帮助我。有人可以帮忙吗?提前致谢。一些代码将不胜感激。这是我的:

//temp_folder is global variable

temp_folder = APPDATA + "Local" + "\\" + "Temp\\";

Thread oThread = new Thread(new ThreadStart(clean_temp));
oThread.Start();

//Here I should wait for this oThread to finish, then change the temp_folder
//variable mentioned in comment down and start once again

//temp_folder = WINDIR + "\\" + "Temp\\";
//oThread.Start();

这是一个clean_temp()过程。是的,这是GUI应用程序。

public void clean_temp()
{
DirectoryInfo directory = new DirectoryInfo(temp_folder);

try
{
    DirectoryInfo[] folders = directory.GetDirectories();

    foreach (DirectoryInfo folder in folders)
    {
        temp_folder = temp_folder + folder.Name + "\\";
        clean_temp();
        temp_folder = temp_folder.Replace(folder.Name + "\\", "");
    }
}
catch { }

long sz;
double size, trenutna;

foreach (FileInfo file in directory.GetFiles())
{
    sz = file.Length;
    size = (double)sz / 1024.0;
    trenutna = Convert.ToDouble(lbl_junk_size.Text);
    trenutna += size;

    MethodInvoker mi_invoker_size_change = new MethodInvoker(()=> lbl_junk_size.Text = trenutna.ToString());
    lbl_junk_size.Invoke(mi_invoker_size_change);

    MethodInvoker mi_invoker_count_change = new MethodInvoker(() => lbl_junk.Text = (Convert.ToInt64(lbl_junk.Text) + 1).ToString());
    lbl_junk.Invoke(mi_invoker_count_change);
}
}

3 个答案:

答案 0 :(得分:4)

您可以使用Join()来确保您的主题已完成。

例如:

Thread oThread = new Thread(new ThreadStart(clean_temp));
oThread.Start();

oThread.Join();

答案 1 :(得分:2)

我想你在这里问错了。而不是询问如何等待线程完成,你应该看看如何在第一次完成后执行另一个操作。

在大多数情况下,您可以使用Task API in .Net执行此操作。任务为您提供了一种非常简洁的方法来定义要异步执行的操作,然后在完成后执行其他操作。

所以你可能会做这样的伪代码:

var task = new Task(clean_temp);
task.ContinueWith(update_global_variable);
task.ContinueWith(clean_temp);
task.Wait();

实际代码不会完全像这样,但想法是你定义了应该完成的事情(调用clean_temp),然后你定义了在第一个作业完成后要完成的事情(update_global_variable)等等。您可以链接任意数量的操作。

这可能比自己处理线程要干净得多。

编辑: 实际上,您可以通过删除全局变量来进一步简化代码。

如果修改clean_temp方法以获取指定要清理的文件夹的输入参数,那么您可以执行以下操作(再次,伪代码!!!):

new Task(clean_temp, "C:\first temp folder")
   .ContinueWith(clean_temp, "C:\second folder")
   .Wait();

更清洁,更安全: - )

答案 2 :(得分:0)

如果您使用的是C#5,请尝试将线程包装在任务中。任务提供了一种名为' ContinueWith'你可以再次调用你的线程。或者使用' await'

进行异步调用