locked
asynchronous consumer to producer notification possible?

    Pregunta

  • Hi!

    Consider a case in which you have a time consuming calculation to be done for multiple requests threads. For this particular calculation, due to high latency and high throughput in this scenario (GPU), I am considering a design to batch togehter input data from a number of requests threads to single thread that makes the calculation. When the calculation is done, it notifies the request threads that the result is availble.

    Obviously a producer-consumer queue would be suiteful with multiple producers and one consumer. I have a working synchronous solution of this in which the consumer thread notifies the waiting producer threads when the job is done. 

    But now I am investigating if it possible to get an asynchonrous version of the producer threads. I.e. as soon as the producer has left off the input data to the queue they return to the thread pool. When the consumer thread is done it will bring back producer threads from the thread pool and each such thread may return with the result. 

    I see one possible solution by letting the producer threads "async sleep" for a while and regularly poll if the result is available. I would however prefer a direct notification when the consumer has finished instead. Is this possible using the async CTP? 


    Tobias

    domingo, 19 de febrero de 2012 17:06

Respuestas

  • But now I am investigating if it possible to get an asynchonrous version of the producer threads. I.e. as soon as the producer has left off the input data to the queue they return to the thread pool. When the consumer thread is done it will bring back producer threads from the thread pool and each such thread may return with the result. 

    It sounds like what you need - conceptually - is an async enumerator (where the production side uses parallel processing).

    There are the beginnings of an async enumerator solution available. You can watch this video for a conceptual overview, and download it in an expirimental Rx package (that doesn't actually use Rx).

    Currently, though, it's rather awkward, both to write and consume. I am hoping that Microsoft will decide to add "async yield" and "async foreach" to the language, but haven't heard whether or not they're planning to.

    Alternatively, you could go with a dataflow-based solution. This is probably the better approach for now. Dataflow is part of the async CTP, though it seems like most people don't notice it. Using a simple BufferBlock, you can have the consumer "drive," so the producers can (asynchronously) wait for space to become available. You may be able to replace more of your producer logic with dataflow as well.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible

    miércoles, 22 de febrero de 2012 13:05

Todas las respuestas

  • It sounds like you want your request threads to await their calculation, and for all request thread calculations to take place on the same background thread.

    Stephen Toub recently posted a series on making asynchronous synchronization primitives (the first of which is http://blogs.msdn.com/b/pfxteam/archive/2012/02/11/10266920.aspx)

    Assuming i've understood his articles correctly i think you can do something along these lines

    class ConsumerThread {
      public Task Enqueue(object data) {
        TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
        
         // schedule data for processing here
    
        return tcs.Task;
      }
      public void OnProcessData(object data, TaskCompletionSource task) {
        try {
          // do stuff
          
          task.SetResult(data);
        } catch (Exception ex) {
          task.SetException(ex);
        }
      }
    }
    
    public class ProducerThreads {
      public async Task<object> ProduceRequest(object data, ConsumerThread consumer) {
        return await consumer.Enqueue(data);
      }
    }</object><object></object>




    • Editado hannasm domingo, 19 de febrero de 2012 18:48
    domingo, 19 de febrero de 2012 18:45
  • Yes. Thank you. This seems very useful. I'll do some reading and testing with this soon and update this thread when I found what I need in my scenario. Or if I have a follow up question.. :)

    Tobi

    miércoles, 22 de febrero de 2012 11:19
  • But now I am investigating if it possible to get an asynchonrous version of the producer threads. I.e. as soon as the producer has left off the input data to the queue they return to the thread pool. When the consumer thread is done it will bring back producer threads from the thread pool and each such thread may return with the result. 

    It sounds like what you need - conceptually - is an async enumerator (where the production side uses parallel processing).

    There are the beginnings of an async enumerator solution available. You can watch this video for a conceptual overview, and download it in an expirimental Rx package (that doesn't actually use Rx).

    Currently, though, it's rather awkward, both to write and consume. I am hoping that Microsoft will decide to add "async yield" and "async foreach" to the language, but haven't heard whether or not they're planning to.

    Alternatively, you could go with a dataflow-based solution. This is probably the better approach for now. Dataflow is part of the async CTP, though it seems like most people don't notice it. Using a simple BufferBlock, you can have the consumer "drive," so the producers can (asynchronously) wait for space to become available. You may be able to replace more of your producer logic with dataflow as well.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible

    miércoles, 22 de febrero de 2012 13:05