我的教授给了我这个半伪代码。他说我应该在这段代码的逻辑中找到一个错误。目前我找不到任何东西,可能是错的。你能不能给我一些关于可能出错的提示?我不是要求答案,因为我想自己找到答案,但是我应该看到哪些方向的提示会很棒。
class Program
{
int progressValue = 0;
int totalFiles = 0;
int i = 0;
bool toContinue = true;
void MasterThread()
{
Thread thread1 = new Thread(Worker1);
Thread thread2 = new Thread(Worker2);
Thread progressThread = new Thread(ProgressThread);
thread1.Start();
thread2.Start();
progressThread.Start();
}
void Worker1()
{
string[] files = Directory.GetFiles(@"C:\test1");
totalFiles += files.Length;
foreach (string file in files)
{
Encryption.Encrypt(file);
i++;
progressValue = 100 * i / totalFiles;
}
toContinue = false;
}
void Worker2()
{
string[] files = Directory.GetFiles(@"C:\test2");
totalFiles += files.Length;
foreach (string file in files)
{
Encryption.Encrypt(file);
i++;
progressValue = 100 * i / totalFiles;
}
toContinue = false;
}
void ProgressThread()
{
while (toContinue == true)
{
Update(progressValue);
Thread.Sleep(500);
}
}
}
答案 0 :(得分:3)
toContinue = false;
这是在第一个完成线程结束时设置的 - 这将导致ProgressThread在第一个线程完成时立即停止,而不是在两个线程完成时停止。应该有两个单独的线程完成标志,两者都应该被检查。
答案 1 :(得分:1)
要添加已经提供的好答案 ,我有点彻底,但想法是学习。
异常处理
可能是异常处理的问题。请务必检查程序中是否有可能出现意外结果的地方 如果此变量的值不是我们所期望的,那么此代码将如何表现? 如果我们除以零会发生什么? 这样的事情。
看看变量初始化的位置,并问自己是否有可能无法以预期的方式进行初始化?
Exception Handling (C# Programming Guide)
方法调用
还要检查代码中使用的所有库。例如加密。
问问自己,这些陈述会给我一个预期的结果吗?
e.g。
string[] files = Directory.GetFiles(@"C:\test1");
这会返回一个字符串数组吗? 这是我应该如何初始化字符串数组?
询问电话: e.g。
Update(progressValue);
这到底是做什么的?
线程
如何调用这样的三个线程 他们需要协调吗? 线程是否应该睡眠,以便完成其他操作?
同样从不同的线程访问变量 试图追踪该变量的价值会不会有一团糟? 他们被覆盖了吗?
Thread Class
How to: Create and Terminate Threads (C# Programming Guide)
命名约定
在较小的说明中,C#中的命名约定存在问题。使用泛型var
的隐式类型优于C#中的显式类型声明。
C# Coding Conventions (C# Programming Guide)
我并不是说所有这些问题都存在问题,但如果您调查所有这些问题以及其他答案中提出的要点,您会发现所有错误,并且您将更好地了解您正在阅读的代码。
答案 2 :(得分:1)
以下是项目:
MasterThread
”没有任何内容 - 所以很难判断程序是否会立即结束。totalFiles
,如果两个线程同时访问,那么有可能一个或另一个可能获胜(或两者都可能部分更新该值),所以不知道你是否是否有有效值。应该使用Interlocked.Add(ref totalFiles, files.Length);
。i
,这也可能会损坏。应该使用Interlocked.Increment(ref i);
。Encryption.Encrypt
是否是线程安全的。可能应该使用lock
。ProgressThread
中的循环不好 - 应始终避免使用Thread.Sleep
- 最好有一个显式更新调用(或其他机制)来更新进度。Update(progressValue);
是否是线程安全的。可能应该使用lock
。答案 3 :(得分:0)
有一些;我只列举了两个显而易见的问题,我想这不是一个如何编写精确和正确的多线程代码的练习。
您应该问自己以下问题:
progressValue
应衡量总工作从0到100的进度(等于150的进度值似乎有点偏,不是吗?)。这真的是这样吗?progressValue
(Update(progressValue)
)。你真的这样做吗?答案 4 :(得分:0)
我不太了解多线程,但是我试图提供一些提示。 首先看一下全局变量,当你在不同的线程中访问同一个变量时会发生什么?
除了对另一个答案的提示外,我找不到其他任何东西"错误"。