views:

137

answers:

4

If I have a that thread:

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

will, the Tick event of the timer will be on the main thread or on the sendMessage thread?

Edit: I have a queue and i want that every x milisecond the timer will tick and the program will dequeue arrays from the queue, but this is my code:

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)
            {

            }

and I can't call a none static method or use a none static field from the checkIfQueue, and it have to be static, what can i do?

Edit: Here is the code that one of you sent me, I cahnged him so it fitts to my goal, will it work?

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();
        }
+5  A: 

It depends on the type of timer. Most timers (System.Timers.Timer or System.Threading.Timer) that can work in a background thread use a ThreadPool thread for their Tick event. In this case, the answer is "neither" thread.

If your timer is a Windows Forms timer or a DispatcherTimer, it will likely cause an exception, since they need to be run on the UI thread, and can't be run on a background thread.

Reed Copsey
+3  A: 

This is going to depend on exactly which timer you are using. The .NET Framework has several timers;

  • System.Threading.Timer = Could be on any available thread.
  • System.Windows.Forms.Timer = Should be on the "UI" thread.
  • System.Timer.Timer = Could be on any available thread.

And probably more that I'm missing.

GWLlosa
+2  A: 

As mentioned, there are two timers; System.Threading.Timer and System.Windows.Forms.Timer. The first kind may execute on any thread, except the thread you started it from (unless it's part of the threadpool, and your function has returned, then it might be executed there, eventually.)

The second kind, the Windows Forms kind, may execute on either your thread, or another thread. It depends.

The timer needs a window handle, and depending on which thread the handle is created, the Tick event will fire on different threads. The internal window the timer uses is created when it's needed for the first time. Most likely, you have created the timer on the main (GUI) thread, but that will not create the actual window inside the timer. To ensure that the window is created on the main thread you will have to first start, and then stop, the timer at least one time. (It's when started for the first time the window is created.)

(If you didn't get it: the timer uses an internal window to receive the tick event. The window is created on a thread, and that thread needs to have message loop running. The thread that is first to start the timer will create the window, and receive the Tick event. Hopefully that thread is running a messageloop.)

Onkelborg
+1  A: 

If you are wanting to dequeue items from a queue every X milliseconds then why use a timer at all? It is much easier to spawn a new thread that spins around an infinite loop.

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:

No, your method is not thread-safe. The problem is with how you are dequeueing items.

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

It should really look like this.

if (messageQueue.TryDequeue(out array)
{
}

The TryDequeue method returns false if the queue is empty so it already does the check and dequeue in one atomic operation.

Brian Gideon