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 8859265
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T15:00:59+00:00 2026-06-14T15:00:59+00:00

I have an Action that takes a callback it will call with a generic

  • 0

I have an Action that takes a callback it will call with a generic argument once it completes, i.e. an Action<Action<T>>. I want to show a busy spinner when the action starts and then take it away when it calls the callback so I created a simple utility to do that. The problem I’m having is that the user will expect their callback to run on the original calling thread but it does not always do so. It almost always works perfectly in unit tests (nUnit) but doesn’t work for some calls when the application is actually running (WPF, .Net 4).

Here are the relevant bits of what I have

void WrapAsyncCallbackPattern<T>(Action<T> callback, Action<Action<T>> actionToRun)
{
    var subject = new AsyncSubject<T>();
    try
    {
        actionToRun(
            result =>
            {
                subject.OnNext(result);
                subject.OnCompleted();
            });
    }
    catch (Exception ex)
    {
        subject.OnError(ex);
    }

    subject
        .ObserveOn(Scheduler.CurrentThread)
        .Subscribe(callback, OnError);
}

I want callback to be run on the thread I’m subscribing (and subject is declared on) but it doesn’t seem to do so reliably. I assume that I’m doing something silly. What is it?

Edit: Added unit test code

private readonly TimeSpan m_WaitTime = TimeSpan.FromSeconds(1);

[Test]
public void WrapAsyncCallbackPattern_WithActionOnDifferentThread_CallsCallbackOnSameThread()
{
    var awaiter = new AutoResetEvent(false);

    bool callbackRan = false;
    int callingThreadId = Thread.CurrentThread.ManagedThreadId;
    int callbackThreadId = int.MinValue;
    int actionThreadId = int.MinValue;

    BackgroundOperation.WrapAsyncCallbackPattern<int>(
        _ =>
        {
            callbackRan = true;
            callbackThreadId = Thread.CurrentThread.ManagedThreadId;

            awaiter.Set();
        },
        cb => ThreadPool.QueueUserWorkItem(
            _ =>
            {
                actionThreadId = Thread.CurrentThread.ManagedThreadId;
                cb(0);
            }));

    var errorInfo = string.Format("\r\nCalling thread = {0}; Action thread = {1}; Callback thread = {2}", callingThreadId, actionThreadId, callbackThreadId);

    Assert.IsTrue(awaiter.WaitOne(m_WaitTime));
    Assert.IsTrue(callbackRan);
    Assert.AreNotEqual(callingThreadId, actionThreadId, "Action needs to be run on a different thread for this test." + errorInfo);
    Assert.AreNotEqual(actionThreadId, callbackThreadId, "Callback should not be run on action thread." + errorInfo);
    Assert.AreEqual(callingThreadId, callbackThreadId, "Callback should be run on calling thread." + errorInfo);
}
  • 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-14T15:01:00+00:00Added an answer on June 14, 2026 at 3:01 pm

    You probably have the wrong understanding of what Scheduler.CurrentThread does. I think everyone makes this mistake.

    The CurrentThread scheduler relates to the executing observable and not when it is defined (or subscribed to). Think deferred or lazy execution. This should make sense as whenever you jump to a different thread you need some way of marshalling the call.

    So what you’re really after is something like this:

    var synchContext = new SynchronizationContextScheduler(
        System.Threading.SynchronizationContext.Current) 
    
    subject
        .ObserveOn(synchContext)
        .Subscribe(callback, OnError);
    

    Or maybe:

    subject
        .ObserveOn(this) /* this is my current form */
        .Subscribe(callback, OnError);
    

    If you do that you should be able to control which thread your callbacks get run on.

    Your tests probably worked because they ended up executing synchronously.

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

Sidebar

Related Questions

I have an action that takes a long time. I want to be able
I have an action method that takes in two different objects. I am posting
I'd like to have an Index action for a Users controller that takes an
I have a MVC action that takes one of its parameters a DateTime and
I have a Create action that takes an entity object and a HttpPostedFileBase image.
I have an ActiveRecord transaction that takes place during a web service call. It
I'm kind of confused... I have one action that takes an ID, loads up
I have an action that takes POST data secured by sfGuard. This means that
I have a search action that takes a search parameter. I have search results
I have an action that takes place in Dialog . That action starts another

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.