Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8255611
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T01:35:01+00:00 2026-06-08T01:35:01+00:00

In a WPF application, I have a 3rd party library that is publishing messages.

  • 0

In a WPF application, I have a 3rd party library that is publishing messages.

The messages are like :

public class DialectMessage
{
    public string PathAndQuery { get; private set; }

    public byte[] Body { get; private set; }

    public DialectMessage(string pathAndQuery, byte[] body)
    {
        this.PathAndQuery = pathAndQuery;
        this.Body = body;
    }
}

And I setup the external message source from my app.cs file :

public partial class App : Application
{
    static App()
    {
        MyComponent.MessageReceived += MessageReceived;
        MyComponent.Start();
    }

    private static void MessageReceived(Message message)
    {
        //handle message
    }

}

These messages can be publishing from multiple thread at a time, making possible to call the event handler multiple times at once.

I have a service object that have to parse the incoming messages. This service implements the following interface :

internal interface IDialectService
{
    void Parse(Message message);
}

And I have a default static instance in my app.cs file :

    private readonly static IDialectService g_DialectService = new DialectService();

In order to simplify the code of the parser, I would like to ensure only one message at a time is parsed.

I also want to avoid locking in my event handler, as I don’t want to block the 3rd party object.

Because of this requirements, I cannot directly call g_DialectService.Parse from my message event handler

What is the correct way to ensure this single threaded execution?

My first though is to wrap my parsing operations in a Produce/Consumer pattern. In order to reach this goal, I’ve try the following :

  1. Declare a BlockingCollection in my app.cs :

    private readonly static BlockingCollection<Message> g_ParseOperations = new BlockingCollection<Message>();
    
  2. Change the body of my event handler to add an operation :

    private static void MessageReceived(Message message)
    {
        g_ParseOperations.Add(message);
    }
    
  3. Create a new thread that pump the collection from my app constructor :

    static App()
    {
        MyComponent.MessageReceived += MessageReceived;
        MyComponent.Start();
    
        Task.Factory.StartNew(() =>
        {
            Message message;
            while (g_ParseOperations.TryTake(out message))
            {
                g_DialectService.Parse(message);
            }
        });
    }
    

However, this code does not seems to work. The service Parse method is never called.

Moreover, I’m not sure if this pattern will allow me to properly shutdown the application.

What have I to change in my code to ensure everything is working?

PS: I’m targeting .Net 4.5

[Edit] After some search, and the answer of ken2k, i can see that I was wrongly calling trytake in place of take.

My updated code is now :

    private readonly static CancellationTokenSource g_ShutdownToken = new CancellationTokenSource();

    private static void MessageReceived(Message message)
    {
        g_ParseOperations.Add(message, g_ShutdownToken.Token);
    }

    static App()
    {
        MyComponent.MessageReceived += MessageReceived;
        MyComponent.Start();

        Task.Factory.StartNew(() =>
        {
            while (!g_ShutdownToken.IsCancellationRequested)
            {
                var message = g_ParseOperations.Take(g_ShutdownToken.Token);
                g_DialectService.Parse(message);
            }
        });
    }

    protected override void OnExit(ExitEventArgs e)
    {
        g_ShutdownToken.Cancel();
        base.OnExit(e);
    }

This code acts as expected. Messages are processed in the correct order. However, as soon I exit the application, I get a “CancelledException” on the Take method, even if I just test the IsCancellationRequested right before.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T01:35:02+00:00Added an answer on June 8, 2026 at 1:35 am

    The documentation says about BlockingCollection.TryTake(out T item):

    If the collection is empty, this method immediately returns false.

    So basically your loop exits immediately. What you may want is to call the TryTake method with a timeout parameter instead, and exit your loop when a mustStop variable becomes true:

    bool mustStop = false;  // Must be set to true on somewhere else when you exit your program
    ...
    while (!mustStop)
    {
        Message yourMessage;
    
        // Waits 500ms if there's nothing in the collection. Avoid to consume 100% CPU
        // for nothing in the while loop when the collection is empty.
        if (yourCollection.TryTake(out yourMessage, 500))
        {
            // Parses yourMessage here
        }
    }
    

    For your edited question: if you mean you received a OperationCanceledException, that’s OK, it’s exactly how methods that take a CancellationToken object as parameter must behave 🙂 Just catch the exception and exit gracefully.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a WPF application that uses 3rd party controls (like http://navigationpane.codeplex.com ) which
In my WPF Application I have an GridViewColumn that looks like this: <GridViewColumn Width=170>
In my WPF application I have a View that is given a ViewModel, and
I want my WPF application to have a ToggleButton that contains an image of
I am making a WPF-application.I have a datagrid with a column header that contains
In my Composite WPF application I have an event that is published when the
I have a WPF application that we have integrated credit card processing into. We're
I have a bunch of classes in a C# class library that I bought
I have a WPF application with the main Window class called MainWindow. Since I
I am working on a 3rd party application that allows plugins to be written

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.