2013-07-31 52 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