Список процессов <T>член при добавлении в отдельном потоке - PullRequest
0 голосов
/ 09 июля 2010

Итак, сначала приведу псевдокод того, что я хочу улучшить.

        public List<ProcessData> Processes;
        System.Threading.Thread ProcessThread;
        void ProcessLoop()
        {
            while (true)
            {
                for (int i = 0; i < Processes.Count; i++)
                {
                    if (HasPriority(Processes[i]))
                    {
                        Process(Processes[i]);
                    }
                }
                System.Threading.Thread.Sleep(1000);
            }

        }
        void AddProcessData(ProcessData pd)
        {
            Processes.Add(pd);
            if (Suspended(ProcessThread))
                Resume(ProcessThread);
        }
        void Startup()
        {
            ProcessThread = new System.Threading.Thread(ProcessLoop);
            ProcessThread.Start();
        }

Итак, я хочу заменить 'Sleep' кодом, который приостановит поток или заставит его ждать, покачто-то добавляется в список и затем возобновляется.Мне также нужно, чтобы это было поточно-ориентированным, конечно.

Ответы [ 5 ]

1 голос
/ 09 июля 2010

Что вам действительно нужно, так это BlockingQueue.Вы можете найти качественную реализацию здесь .Или, если вы используете v4 .NET Framework, вы можете использовать встроенный класс BlockingCollection .Обратите внимание, насколько проще код при использовании этого типа структуры данных.

public class YourClass
{
  private BlockingQueue<ProcessData> m_Queue = new BlockingQueue<ProcessData();

  private void ProcessLoop()
  {
    while (true)
    {
      ProcessData item = m_Queue.Dequeue();
      if (HasPriority(item))
      {
        Process(item);
      }
    }
  }

  public void AddProcessData(ProcessData item)
  {
    m_Queue.Enqueue(item);
  }

  public void Startup()
  {
    var thread = new Thread(() => { ProcessLoop(); });
    thread.Start();
  }
}
1 голос
/ 09 июля 2010

То, что вы хотите - это событие.

РЕДАКТИРОВАТЬ: сделать его поточно-ориентированным.

    public List<ProcessData> Processes;
    System.Threading.Thread ProcessThread;
    System.Threading.AutoResetEvent ProcessesChangedEvent = new System.Threading.AutoResetEvent(false);
    void ProcessLoop()
    {
        while (true)
        {
            // You might want to copy out the entire list as an array instead 
            // if HasPriority or Process take a long time.
            lock (Processes)
            {
                for (int i = 0; i < Processes.Count; i++)
                {
                    if (HasPriority(Processes[i]))
                    {
                        Process(Processes[i]);
                    }
                }
            }
            ProcessesChangedEvent.WaitOne(...); // timeout?
        }

    }
    void AddProcessData(ProcessData pd)
    {
        lock (Processes)
            Processes.Add(pd);
        ProcessesChangedEvent.Set(); // you can also use Monitor.PulseAll/Wait
    }
    void Startup()
    {
        ProcessThread = new System.Threading.Thread(ProcessLoop);
        ProcessThread.Start();
    }
1 голос
/ 09 июля 2010

В вашем случае лучше всего использовать один из следующих классов: ManualResetEvent или AutoResetEvent

0 голосов
/ 09 июля 2010

На тот случай, если вам действительно нужно обработать данные только один раз, вот код


        public Queue<ProcessData> Processes;
        System.Threading.Thread[] ProcessThreads = new System.Threading.Thread[5];
        System.Threading.Semaphore semToDo = new System.Threading.Semaphore(0,int.MaxValue);

        void ProcessLoop()
        {
            ProcessData pd; 

            while (true)
            {
                semToDo.WaitOne();
                lock (Processes)
                {
                    pd = Processes.Dequeue();                    
                }
                Process(pd);
            }
        }

        private void Process(ProcessData processData)
        {
            throw new NotImplementedException();
        }

        void AddProcessData(ProcessData pd)
        {
            lock (Processes)
            {
                Processes.Enqueue(pd);
            }
            semToDo.Release();
        }
        void Startup()
        {
            //you can even have multiple worker threads now!

            for(int i = 0; i < 5; i++)
                ProcessThreads[i] = new System.Threading.Thread(ProcessLoop);
            foreach (System.Threading.Thread t in ProcessThreads)
            {
                t.Start();
            }
        }
0 голосов
/ 09 июля 2010

Познакомьтесь с платформой RX от Microsoft.http://rxwiki.wikidot.com/start там вы можете получать событие каждые x секунд и что-то делать.нет необходимости запускать потоки вообще.

или использовать таймер и выполнить проверку в прошедшем событии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...