2013-07-31 176 views
1

請看下面的代碼。 我在C#中使用MultiThreading來解決問題。 這個例子來自一些手冊。 在我的主要功能,我嘗試創建三個線程。線程創建

你能告訴我兩個線程(有錯誤)應該如何正確創建?
謝謝!

using System;  
using System.Threading;  


public static class MonitorMethodAccess 
{ 
    private static int numericField = 1; 
    private static object syncObj = new object(); 

public static object SyncRoot 
{ 
    get { return syncObj; } 
} 

public static void IncrementNumericField() 
{ 
    if (Monitor.TryEnter(syncObj, 250)) 
    { 
     try 
     { 
      ++numericField; 
     } 
     finally 
     { 
      Monitor.Exit(syncObj); 
     } 

    } 
} 

public static void ModifyNumericField(int newValue) 
{ 
    if (Monitor.TryEnter(syncObj, 250)) 
    { 
     try 
     { 
      numericField = newValue; 
     } 
     finally 
     { 
      Monitor.Exit(syncObj); 
     } 
    } 
} 

public static int ReadNumericField() 
{ 
    if (Monitor.TryEnter(syncObj, 250)) 
    { 
     try 
     { 
      return (numericField); 
     } 
     finally 
     { 
      Monitor.Exit(syncObj); 
     } 
    } 

    return (-1); 
} 

}

class Program 
{ 
    static void Main(string[] args) 
    { 
     Thread aaa = new Thread(MonitorMethodAccess.IncrementNumericField); 
     Thread bbb = new Thread(MonitorMethodAccess.ModifyNumericField(12);//error 
     Thread ccc = new Thread(MonitorMethodAccess.ReadNumericField);//error 

     Console.ReadKey(); 
    } 
} 
+1

這可能是一個複製粘貼錯誤,但是你錯過了密切的')'在' Program.Main'。應該是'Thread bbb = new Thread(MonitorMethodAccess.ModifyNumericField(12));' – Jacob

+0

他們仍然使用'.Start()'方法啓動線程嗎? (即使'aaa'看起來就像坐在那裏一樣。) – 2013-07-31 21:09:11

回答

1
Thread bbb = new Thread(()=>MonitorMethodAccess.ModifyNumericField(12)); 
Thread ccc = new Thread(() => MonitorMethodAccess.ReadNumericField()); 

但是,如果你想返回從線程值作爲你的第三個線程,你應該考慮使用Tasks

+0

我想說除了非常罕見的特殊情況外,應該使用任務,而不僅僅是當你想返回一個值時。 –

+0

它編譯和工作正常。我正在努力瞭解lambda表達式在這裏的工作方式...有什麼建議嗎? –

+0

您的第二個線程需要一個參數,因此您應該使用* ParameterizedThreadStart *開始它,第三個不是* void *。所以我把它們全部替換爲'使用lambda表達式來代替void SomeAction()'(注意這些細節)。 – I4V

2

問題是純粹的語法。當你寫

MonitorMethodAccess.IncrementNumericField 

這個表達式計算方法本身。當你寫

MonitorMethodAccess.IncrementNumericField() 

這個表達式的方法的調用的結果,在這種情況下void。您不能將void傳遞給線程,它需要一個方法或一個委託,並且不會接受任何參數。現在的問題是如何實現傳遞一個方法和一些特定的參數?正如I4V指出的那樣,你可以在lambda表達式包起來,其本身不帶參數:

Action methodInvocation = (Action)(() => MonitorMethodAccess.ModifyNumericField(12)); 
Thread bbb = new Thread(methodInvocation); 
+0

注意:線程確實帶有一個'object'參數的方法(即:ParameterizedThreadStart)。此外,ThreadStart可能是一個非靜態的類或其他類的類方法。這是從Action,Task和lambda在C#中不存在的延續。 – 2013-08-01 13:25:08