Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When you deal with a typical "flow" of processing, possibly even multithreaded/concurrent processing flow the best approach to take is "mailslots"/message pumps. By exchaging messages you can easily coordinate multiple layers of your application and that includes reporting errors, notifying the next chain of command etc.. I do not mean Windows messages, I mean something like:</p> <pre><code>public abstract class Message { public abstract void Process(); } </code></pre> <p>Then:</p> <pre><code>public class MessageQueue { private Queue m_Queue; public void Post(Message msg) {....} public void Process() {.....} } </code></pre> <p>Then you allocate a MessageQueue on every thread/processing tier of your app and pass messages like so:</p> <pre><code> GUIMessageQueue.Post( new ErrorMessage("Internal async file reader ran out of buffer")); </code></pre> <p>On GUI thread put a timer that read GUI queue and calls it's Process(). Now you can create many Message-derived work items to execute various tasks that very easily orchestrate between threads/logical tiers. Also, messages may contain references for datapieces that they relate to:</p> <p>public AirplaneLandedMessage: Message { public Airplane Plane ...... }</p> <p>Here is some real code that I use in massively parallel chain-processing system:</p> <pre><code>/// &lt;summary&gt; /// Defines a base for items executable by WorkQueue /// &lt;/summary&gt; public interface IWorkItem&lt;TContext&gt; where TContext : class { /// &lt;summary&gt; /// Invoked on an item to perform actual work. /// For example: repaint grid from changed data source, refresh file, send email etc... /// &lt;/summary&gt; void PerformWork(TContext context); /// &lt;summary&gt; /// Invoked after successfull work execution - when no exception happened /// &lt;/summary&gt; void WorkSucceeded(); /// &lt;summary&gt; /// Invoked when either work execution or work success method threw an exception and did not succeed /// &lt;/summary&gt; /// &lt;param name="workPerformed"&gt;When true indicates that PerformWork() worked without exception but exception happened later&lt;/param&gt; void WorkFailed(bool workPerformed, Exception error); } /// &lt;summary&gt; /// Defines contract for work queue that work items can be posted to /// &lt;/summary&gt; public interface IWorkQueue&lt;TContext&gt; where TContext : class { /// &lt;summary&gt; /// Posts work item into the queue in natural queue order (at the end of the queue) /// &lt;/summary&gt; void PostItem(IWorkItem&lt;TContext&gt; work); long ProcessedSuccessCount{get;} long ProcessedFailureCount{get;} TContext Context { get; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload