1

请看下面的代码。我正在了解 C# 中的多线程。该示例取自一些手册。在我的 Main 函数中,我尝试创建三个线程。

您能否告诉我应该如何正确创建两个线程(有错误)?
谢谢!

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

2 回答 2

2

这个问题纯粹是句法问题。当你写

MonitorMethodAccess.IncrementNumericField

此表达式计算为方法本身。当你写

MonitorMethodAccess.IncrementNumericField()

在本例中,此表达式计算方法调用的结果void。您不能传递void给线程,它需要一个方法或一个委托,以及一个不带任何参数的方法或委托。现在的问题是如何实现传递一个方法和一些具体的参数?正如 I4V 所指出的,您可以将其包装在 lambda 表达式中,该表达式本身不带参数:

Action methodInvocation = (Action)(() => MonitorMethodAccess.ModifyNumericField(12));
Thread bbb = new Thread(methodInvocation);
于 2013-07-31T21:13:30.157 回答
1
Thread bbb = new Thread(()=>MonitorMethodAccess.ModifyNumericField(12));
Thread ccc = new Thread(() => MonitorMethodAccess.ReadNumericField());

但是,如果您想像在第三个线程中一样从线程返回值,您应该考虑使用Tasks

于 2013-07-31T21:03:49.833 回答