2016-09-03 139 views
3

我的教授給了我這個半僞代碼。他說我應該在這段代碼的邏輯中找到一處錯誤。目前我找不到任何東西,可能是錯的。你能給我一些關於什麼可能是錯誤的提示嗎?我並沒有要求回答,因爲我想自己找到答案,但是我應該看到什麼方向的一些提示會很棒。多線程程序邏輯

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

併發訪問變量? –

+0

我給了這個問題,所有的答案upvote,我認爲這是一個偉大的問題風格。這實際上很有趣。 –

+1

謝謝大家的回答和你花在回答和嘗試幫助我的時間!我一定會研究你指出的所有事情!謝謝! – Martin

回答

1

添加到已經提供的良好答案,我有點徹底,但想法是學習。

異常處理

可能是與異常處理的問題。請始終檢查您的計劃是否有可能出現意外結果的地方。
如果此變量的值不符合我們的預期,此代碼將如何運行?
如果我們除以零會發生什麼?
這樣的事情。

看看變量初始化的地方,問自己是否有可能無法按照預期的方式進行初始化?

Exception Handling (C# Programming Guide)

方法調用

還檢查了在代碼中使用任何庫。例如加密。
問問自己,這些陳述會給我一個預期的結果嗎? 例如

string[] files = Directory.GetFiles(@"C:\test1"); 

這會返回一個字符串數組嗎?
這是我應該如何初始化一個字符串數組?

提問電話: 例如

Update(progressValue); 

這究竟是什麼呢?

Class Library

線程

將如何工作調用三個線程這樣。
他們需要協調嗎?
線程應該睡覺,以允許其他操作完成?

同樣用於訪問來自不同線程的變量。
是否會試圖追蹤變量的值?
他們被覆蓋?

Thread Class
How to: Create and Terminate Threads (C# Programming Guide)

命名約定

在一個較小的注意,有C#中的命名約定的問題。使用通用的var的隱式類型比C#中的顯式類型聲明更受歡迎。

C# Coding Conventions (C# Programming Guide)

我不是說有所有這些點的問題,但如果你調查所有這些以及其他的答案提出的觀點,你會發現所有的錯誤,你會得到一個更好地理解你正在閱讀的代碼。

0

有幾個;我只列舉兩個明顯的例子,我假設這不是一個如何編碼精確和正確的多線程代碼的練習。

你應該問自己以下問題:(?前進值等於150,似乎有點過,不是麼)

  1. progressValue應該測量從零到工作百元進展。這是真的嗎?
  2. 您不應該停止更新progressValueUpdate(progressValue)),直到完成所有工作。你真的這麼做嗎?
+0

謝謝你突出這兩個,我會研究他們。實際上這個主題被稱爲多線程編程,所以它可能會在多線程部分的邏輯中出現一些錯誤。你能看到嗎? – Martin

+1

@Martin我剛剛爲你指出了兩個。 – InBetween

0

我不太瞭解多線程,但生病嘗試給出一個提示的轎跑車。 首先看全局變量,當你在不同的線程中訪問同一個變量時會發生什麼?

除了對其他答案的提示,我找不到任何「錯誤」。

3
toContinue = false; 

這是設置爲第一完成線程結束 - 這將導致ProgressThread儘快第一個線程完成停止,而不是當兩個線程完成。應該有兩個單獨的線程完成標誌,兩者都應該被檢查。

1

這裏是項目:

  1. 沒有什麼舉行對「MasterThread」 - 所以這是很難說,如果該程序將立即結束與否。
  2. 從兩個線程訪問totalFiles,如果兩者都同時進行,則可能一方或另一方可能獲勝(或兩者都可能部分更新該值),因此不知道您是否具有有效值或不。應該使用Interlocked.Add(ref totalFiles, files.Length);
  3. 這兩個工作線程也更新i,這也可能會損壞。應該使用Interlocked.Increment(ref i);
  4. 不知道Encryption.Encrypt是否是線程安全的。應該使用lock
  5. ProgressThread中的循環錯誤 - 應始終避免使用Thread.Sleep - 最好有顯式更新調用(或其他機制)來更新進度。
  6. 不知道Update(progressValue);是否是線程安全的。應該使用lock