2010-10-22 4 views
3

Если у меня есть что нить:Вопросы о многопоточности

Thread sendMessage = new Thread(new ThreadStart(timer.Start())); 

воли, событие Tick таймера будет в основном потоке или на резьбе SendMessage?

Edit: У меня есть очереди, и я хочу, чтобы каждый х milisecond таймер будет тикать и программа из очереди массивов из очереди, но это мой код:

Thread sendMessage = new Thread(new ThreadStart(startThreadTimer)); 
      public Queue<Array> messageQueue = new Queue<Array>(); 
System.Threading.Timer timer; 
      private void startThreadTimer() 
      { 
       System.Threading.TimerCallback cb = new System.Threading.TimerCallback(checkIfQueue); 
       timer = new System.Threading.Timer(cb, null, 4000, 30); 
      } 
      private static void checkIfQueue(object obj) 
      { 

      } 

и я могу 't вызывать не статический метод или использовать не статическое поле из checkIfQueue, и оно должно быть статическим, что я могу сделать?

Edit: Вот код, который один из вас послал меня, я cahnged его так Fitts к своей цели, будет ли он работать?

public ConcurrentQueue<Array> messageQueue = new ConcurrentQueue<Array>(); 
public void Example() 
     { 
      var thread = new Thread(
      () => 
      { 
       while (true) 
       { 
        Array array; 
        byte[] byteArray = {}; 
         if (messageQueue.Count > 0) 
         { 
          messageQueue.TryDequeue(out array); 
          foreach (byte result in array) 
          { 
           byteArray[byteArray.Length] = result; 
          } 
          controllernp.Write(byteArray, 0, 100); 
         } 

        Thread.Sleep(30); 
       } 
      }); 
      thread.IsBackground = true; 
      thread.Start(); 
     } 
+2

Этого не будет нигде. Вы не можете запустить программу, пока не будете писать код, который компилируется. –

+5

@ Ханс - такое отношение на самом деле не помогает. Вы могли бы хотя бы указать, какая часть программы неправильная, а не просто душ. – Dismissile

+0

@ Dis - все это неправильно. Я не могу разумно ответить на вопрос, основанный на коде, который не может работать. –

ответ

1

Если вы хотите деактивировать элементы из очереди каждые X миллисекунд, то зачем вообще использовать таймер? Гораздо проще создать новый поток, который вращается вокруг бесконечного цикла.

public class Example 
{ 
    private ConcurrentQueue<Array> m_Queue = new ConcurrentQueue<Array>(); 

    public Example(int intervalMilliseconds) 
    { 
    var thread = new Thread(
    () => 
     { 
     while (true) 
     { 
      Array array; 
      while (m_Queue.TryDequeue(out array)) 
      { 
      // Process the array here. 
      } 
      Thread.Sleep(intervalMilliseconds); 
     } 
     }); 
    thread.IsBackground = true; 
    thread.Start(); 
    } 

    public void Enqueue(Array array) 
    { 
    m_Queue.Enqueue(array); 
    } 
} 

Update:

Нет, ваш метод не поточно-. Проблема заключается в том, как вы меняете объекты.

if (messageQueue.Count > 0) 
{ 
    messageQueue.TryDequeue(out array); 
} 

Это должно быть действительно так.

if (messageQueue.TryDequeue(out array) 
{ 
} 

Метод TryDequeue возвращает ложь, если очередь пуста, так что уже делает чек и DEQUEUE в одной атомарной операции.

5

Это зависит от типа таймера. Большинство таймеров (System.Timers.Timer или System.Threading.Timer), которые могут работать в фоновом потоке, используют поток ThreadPool для своего события Tick. В этом случае ответ «нить».

Если ваш таймер является таймером Windows Forms или DispatcherTimer, это, скорее всего, вызовет исключение, поскольку они должны запускаться в потоке пользовательского интерфейса и не могут выполняться в фоновом потоке.

3

Это зависит от того, какой именно таймер вы используете. .NET Framework имеет несколько таймеров;

  • System.Threading.Timer = Может быть на любой доступной нити.
  • System.Windows.Forms.Timer = Должен быть в потоке «UI».
  • System.Timer.Timer = Может быть на любой доступной нити.

И, вероятно, больше того, что мне не хватает.

2

Как уже упоминалось, существует два таймера; System.Threading.Timer и System.Windows.Forms.Timer. Первый вид может выполняться в любом потоке, кроме потока, с которого вы его начали (если только он не является частью потока thread, и ваша функция вернулась, то он может быть выполнен там, в конце концов.)

Второй вид, Windows Вид форм, может выполняться либо на вашем потоке, либо на другом потоке. Это зависит.

Таймер требует ручку окна, и в зависимости от того, какой поток создается дескриптор, событие Tick будет срабатывать в разных потоках. Внутреннее окно, которое использует таймер, создается, когда оно требуется в первый раз. Скорее всего, вы создали таймер на основном (GUI) потоке, но это не создаст фактическое окно внутри таймера. Чтобы убедиться, что окно создано в основном потоке, вам нужно сначала запустить, а затем остановить таймер, по крайней мере, один раз. (Это когда при первом запуске создается окно.)

(Если вы его не получили: таймер использует внутреннее окно для получения события тика. Окно создается по потоку, и этот поток должен быть запущен цикл сообщений. Поток, который первым запускает таймер, создаст окно и получит событие Tick. Надеюсь, что в этом потоке запущен messageloop.)