Question

I have a producer/consumer pattern, where I need to inform the producer when the item has been consumed sucessfully. Basically a producer gives me an TransportTask an Action<TransportTask> to call when its ready. What I want to do is post it in the same SyncContext where it came from.

public class TaskProcessAgent : ITaskProcessAgent
{
    private Dictionary<TransportTask, Tuple<Action<TransportTask>, SynchronizationContext>> m_tasks = new Dictionary<TransportTask, Tuple<Action<TransportTask>, SynchronizationContext>>();
    private BlockingCollection<TransportTask> m_taskQueue = new BlockingCollection<TransportTask>();
    private TaskCoordinator m_coordinator;

    public TaskProcessAgent(TaskCoordinator coordinator)
    {
        m_coordinator = coordinator;
        m_coordinator.OnTaskReady += OnTaskReady;

        Task.Factory.StartNew(() =>
            {
                foreach (var _task in m_taskQueue.GetConsumingEnumerable())
                    ProcessTask(_task);
            },
            TaskCreationOptions.LongRunning);
    }

    public void Process(TransportTask task, Action<TransportTask> onReady)
    {
        lock (m_tasks)
        {
            m_tasks.Add(task, Tuple.Create(onReady, SynchronizationContext.Current ?? new SynchronizationContext()));
        }
        m_taskQueue.Add(task);
    }

    public void SetCompleted(TransportTask task)
    {
        m_coordinator.SetCompleted(task);
    }

    private void OnTaskReady(TransportTask task)
    {
        m_tasks[task].Item2.Post(p => m_tasks[task].Item1(task), null);
    }

    private void ProcessTask(TransportTask transportTask)
    {
        m_coordinator.AddTask(transportTask);
    }
}

Here OnTaskReady will be called by TaskCoordinator from it's own thread. What I want is to call the callback from the same SychronizationContext which called Process.

I'm not sure it's going to work and I need to write a lot more code to get to a point where I can test whether it works. The crucial line is m_tasks[task].Item2.Post(p => m_tasks[task].Item1(task), null); and I'm not sure it works this way.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top