Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task.Factory.StartNew not executing the task when deployed

I have some code here that works as expected when I install it / run it on my own computer, Windows 7, but when I run it on other servers (2003 and 2008) it does not. The code is from a .NET4 WCF Service Library that I use in a Windows service. Here it is, simpllified.

public void monitorQueueAndDoStuff() {
  MonitorRetryQueue();
  MonitorMainQueue();                
}

private void MonitorMainQueue() {
  Log.Info("MonitorMainQueue called");
  Task.Factory.StartNew(() =>
  {
    Log.Info("new thread monitoring queue");
    // ...NMS stuff

        while (!stopped) {
          ITextMessage mess = null;
            mess = blockingMessageCollection.Take();
            sendToQueue(mess);
        }
      }
    }
  });
}


private void MonitorRetryQueue() {
  Task.Factory.StartNew(() =>
  {
    //...NMS stuff
        consumer.Listener += new MessageListener(OnRetryErrorMessage);
        Log.Info("new thread monitoring second queue");

        //need to be constantly up for the consumer to hang around
        while (!stopped) {
          Thread.Sleep(1000);
        }
      }
    }
      });
}

The threads should enter loops to do some work. The main one blocks on a BlockingCollection. Now, it creates both tasks but it only enters the second, it never prints "new thread monitoring queue" in the log. I cannot grasp why not. I tried Remote Debugging but as it never enters the code I couldn't see anything of value.

I haven't found anything that would change the behavior of the code on the deployed server. Anyone here might have a clue? Any settings in the Visual Studio project?

like image 879
ejpb Avatar asked Aug 17 '12 17:08

ejpb


People also ask

What is difference between Task run and Task factory StartNew?

Task. Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!

What does task factory StartNew do?

StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.

How do I run a task in C#?

To start a task in C#, follow any of the below given ways. Use a delegate to start a task. Task t = new Task(delegate { PrintMessage(); }); t. Start();

What is difference between task and thread in C#?

Differences Between Task And ThreadThe Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result.


2 Answers

Sometimes this kind of behaviour is an indication of an overloaded ThreadPool.

Seeing as these are long running/blocking tasks, they should not be scheduled to run in the ThreadPool, which is where Task.Factory.StartNew will be sending them using the default TaskScheduler.

IMO, Task.Factory.StartNew is probably not best suited to this, and you'd be better off spinning up your own threads to run these loops.

ThreadStart action=()=>{
    //do your thing
};
Thread thread=new Thread(action){IsBackground=true};
thread.Start();
like image 175
spender Avatar answered Nov 08 '22 05:11

spender


Do any log messages get printed in the log? Do you see "MonitorMainQueue called" get printed? How do you know the second Task is started but not the first? Could it be a permission issue with creating/writing to the log file?

Edit: Additionally, in response to what @spender said about long running tasks, there is an overload to start the task with that option.

Task.Factory.StartNew(MonitorMainQueue, TaskCreationOptions.LongRunning);

like image 31
Paccc Avatar answered Nov 08 '22 07:11

Paccc