单线程多线程

时间:2014-01-09 11:45:45

标签: c# multithreading singleton

我正在为中央服务器开发一个打印队列,负责根据需要将打印作业定向到不同的服务器。

我这样做是作为具有“打印”端点的WCF服务。这一切都很好,我已经设置了这个,但是我正在尝试开发一个线程安全端点,它也可以返回排队线程数的计数。

下面是一个示例类,它触发多个线程并将它们发送到“Print”方法(这模拟了多个人同时点击终点的行为)

public class ThreadStuff
{
    #region [Singleton Logic]

    private static ThreadStuff _instance;

    private ThreadStuff() { }

    private static ThreadStuff Instance
    {
        get { return _instance ?? (_instance = new ThreadStuff()); }
    }

    #endregion

    private static readonly object LockObject = new object();
    private int _queuedThreads;

    public static int QueuedThreads
    {
        get { return Instance._queuedThreads; }
    }

    public static void Start()
    {
        var threads = new Thread[10];
        for (var i = 0; i < 10; i++)
        {
            var threadNumber = i;
            var t = new Thread(() => Instance.MyMethod(threadNumber));
            threads[i] = t;
        }
        for (var i = 0; i < 10; i++)
        {
            var threadNumber = i;
            Thread.Sleep(50);
            threads[i].Start();
            Console.WriteLine("Thread {0} started", threadNumber);
        }

        Console.ReadKey();
    }

    private void MyMethod(int threadNumber)
    {
        Console.WriteLine("Thread {0} entered MyMethod", threadNumber);
        Instance._queuedThreads++;

        lock (LockObject)
        {
            Console.WriteLine("Thread {0} entered MyMethod's Lock", threadNumber);
            Thread.Sleep(2000);
            Console.WriteLine("Thread {0} finished Thread.Sleep", threadNumber);
        }

        Instance._queuedThreads--;
        Console.WriteLine("Thread {0} exited MyMethod", threadNumber);
    }
}

这可以按预期工作并产生以下内容:

但是,我在我的解决方案中添加了另一个项目,该项目将访问此单例的“QueuedThreads”属性(模拟轮询终点的行为)。

这个项目是一个简单的win form app,代码如下

textBox1.Text = ThreadStuff.QueuedThreads.ToString(CultureInfo.InvariantCulture);

但是,这总是返回0,winforms应用程序无法看到“ThreadStuff”类的Singleton数据,它会创建一个新的ThreadStuff实例。我已经把这个问题围绕着我的办公室,没有人能看出为什么会发生这种情况,经过多次谷歌搜索我决定在这里问。

非常感谢任何帮助

2 个答案:

答案 0 :(得分:1)

尝试这种模式:

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

答案 1 :(得分:1)

案例可能是因为它有两个不同的进程,一个控制台应用程序和一个WinForm应用程序。只要是这种情况,您需要进行一些类型的interprosess通信,以使WinForm应用程序能够查看排队的请求。有几种方法可以做到这一点。一些可能性

  • 将值存储在数据库中并从WinForm应用程序中读取它
  • 使用消息队列/总线并发布WinForm应用程序侦听的消息
  • 命名管道
  • 插座
  • 等等