2014-09-02 95 views
1

所以我做了一个线程,它执行一个依赖于全局变量的函数。之后,我想更改该变量并再次运行该线程,以便使用另一个参数再次执行我的过程。问题是,我似乎无法弄清楚我的线程何时完成。经过大量的谷歌搜索,我找不到任何可以帮助我的东西。有人可以帮忙吗?提前致谢。一些代码将不胜感激。这里是我的:开始相同的线程两次 - 第一次完成后的第二次

//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); 
} 
} 
+0

改为使用['ThreadPool'类](http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx),IMO。 – 2014-09-02 11:54:14

+1

是Windows GUI应用程序的主线程部分?或者你打算在清理过程中做其他事情? – 2014-09-02 11:57:16

+0

你可以考虑使用'Task',它有一个'ContinueWith'方法。 – CompuChip 2014-09-02 11:58:35

回答

4

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

如:

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

oThread.Join(); 
+0

试过这个,但由于某种原因,我的程序冻结时,我这样做:/ – 2014-09-02 11:57:41

+2

它会冻结,因为Join()使主线程等待,直到线程完成。 – 2014-09-02 11:58:23

+0

@DivineNeos:你能告诉我们你的clean_temp()实现吗? – Ksv3n 2014-09-02 11:59:46

0

如果您正在使用C#5,尽量在任务中包装你的线程。任务提供了一种名为“ContinueWith”的方法,您可以在其中再次调用您的线程。或异步呼叫与'等待'

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(); 

更清洁,更安全: - )

+0

应用程序是Windows GUI应用程序的一部分。它清理临时文件夹并对标签中清除的文件进行计数。当我写这样的东西时,它会冻结:S你知道为什么吗? var task = new Task(clean_temp); 任务TASK2 = task.ContinueWith((续)=> { \t temp_folder = APPDATA + “​​本地” + “\\” + “温度\\”; }); \t clean_temp(); });() task.Wait(); – 2014-09-02 12:15:26

+0

你的代码非常复杂(你为什么要做Method.Invoke调用?),所以很难说清楚。你应该使用调试器,看看会发生什么。此外,你有一个尝试赶上,在捕获中什么都不做。那里也可能有各种各样的错误。 – 2014-09-02 12:20:16

+0

现在我编辑了代码,将自己的主题封装在Task中,不再工作。你有什么想法如何解决这个问题?因为我认为问题在于它是一个GUI应用程序。 – 2014-09-02 12:29:26

相关问题