-1

During WCF events called by web clients my WCF Server needs to Start a new asynchronous Task on each call but with a delay of more then a minute.

My current solution consists on Task.Factory.StartNew(() => DoTask()); where DoTask() calls await Task.Delay(XXX); before executing its code. This WCF event happens allot in our production environment which causes a creation of many threads that remain stuck for a whole minute.

One of the solutions I have thought of was to use Task.Delay(XXX).ContinueWith((i) => DoTask()); In this solution no threads are created until DoTask() begins to run but I see 2 task that are created for Task.Delay() call.

Which solution is better (or maybe neither...) Creating many threads or creating many Tasks? Thanks.

Shay Lin
  • 1
  • 1
  • 1
    'better' In which concept? performance? resource consumption? ... – Rezaeimh7 Feb 02 '21 at 07:44
  • WCF? Are you doing *very slow* responses or you trying to do background execution? Different unrelated solutions depending on what you want... or if you actually mean WCF... – Alexei Levenkov Feb 02 '21 at 07:46
  • 1
    "which causes a creation of many threads that remain stuck for a whole minute" - it shouldn't. How are you observing that? It may cause several threads to be started within the thread-pool, but I wouldn't expect any to be "stuck". (It's not clear why you're calling StartNew rather than just executing the async method, admittedly.) – Jon Skeet Feb 02 '21 at 07:49
  • Why reinvent the wheel? Scheduling Frameworks have the ability to schedule delayed jobs. e.g. [Hangfire](https://docs.hangfire.io/en/latest/background-methods/calling-methods-with-delay.html) (not affiliated) – Fildor Feb 02 '21 at 07:49
  • 1
    https://blog.stephencleary.com/2013/11/there-is-no-thread.html – Caius Jard Feb 02 '21 at 08:02
  • @JonSkeet I have created a dump file from production and I opened and debugged it on my dev machine . then I saw about 800 threads of the DoTask() – Shay Lin Feb 02 '21 at 11:19
  • 1
    @ShayLin: It's hard to help with only that small amount of information. If the duplicate doesn't already help you, please edit the post to show a [mcve]. – Jon Skeet Feb 02 '21 at 11:34

1 Answers1

0

This event happens allot in our production environment which causes a creation of many threads that remain stuck for a whole minute.

It should not. It will take a thread pool thread to start DoTask(), but when it reaches await Task.Delay(XXX); it should release the thread back to the pool. You will have great deal of tasks, but that is usually not a problem. That is the point of await, that it releases the used thread to do whatever, while allowing it, or another thread, to resume execution at a later time.

One of the solutions I have thought of was to use Task.Delay(XXX).ContinueWith((i) => DoTask()); In this solution no threads are created until DoTask() begins to run but I see 2 task that are created for Task.Delay() call.

If you run this on the main thread the ContinueWith should use the TaskScheduler.Current and thus run DoTask on the main thread. You could change this to TaskScheduler.Default to run in on the threadpool instead. If it is ok to run DoTAsk on the main thread then you could just use await.

Which solution is better (or maybe neither...) Creating many threads or creating many Tasks? Thanks.

Creating many tasks is better. A thread requires a stack and other overhead. The main purpose of tasks is to reduce the need for this overhead.

JonasH
  • 28,608
  • 2
  • 10
  • 23