How to detect if on foreground thread or not in Core from class assembly

RHaggard

New member
Joined
Sep 29, 2019
Messages
3
Programming Experience
10+
In Framework, this is easily accomplished by including a reference to the PresentationFramework class assembly and then using something like this:

public static void UIThread( Action action )
{
if (Application.Current.Dispatcher.CheckAccess())
{
// On FG thread. Can directly invoke the action.
action.Invoke();
}
else
{
// On BG thread. Must do an invoke to get on FG.
Application.Current.Dispatcher.Invoke( action );
}
}

I'm in a Core framework and needed to know if the code in a class library was executing on a foreground thread or in the background and, if BG, then it would need to make the transition to FG. I attempted to add PresentationFramework to my class library module. Hmm. Visual Studio doesn't seem to want me to do that.
Add Reference doesn't work the same. It doesn't have the same ability to add PresentationFramework.dll to the references. Similarly, managing Nuget Packages doesn't really seem to want to insert a reference to PresentationFramework.dll.

Hours later, I've given up on discovering the secret for myself. Time to ask the community. So, how does one figure out if the current thread is FG or not in Core when in a class library DLL module?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,386
Location
Chesapeake, VA
Programming Experience
10+
Are asking about UI thread or foreground thread?

A return value of false for Thread.IsBackground should indicate that a thread is a foreground thread.
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,921
Location
Sydney, Australia
Programming Experience
10+
Whether you're targeting .NET Framework or .NET Core, you should do it the same way. Use the SynchronizationContext class and call its Send or Post method to ensure a method is executed on the UI thread. You should ditch what you were already doing.
 

RHaggard

New member
Joined
Sep 29, 2019
Messages
3
Programming Experience
10+
The basic problem is this:
The environment is WPF/Core/Class Library.
The goal is to detect if a method is operating on the foreground or background and, if BG, transition to foreground and assert some values to properties that are bound to UI elements.

In Framework, the standard method for detecting FG vs BG and performing a transition to from BG to FG is to leverage the Application class. This works in both applications and class libraries. I'm now working on a core project, not a framework project, and attempts to use Application in the class libraries appears to no longer be supported. While still maintaining MVVM compliance, what is the accepted best practice in a Core environment to accomplish this task?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,386
Location
Chesapeake, VA
Programming Experience
10+
In Framework, the standard method for detecting FG vs BG and performing a transition to from BG to FG is to leverage the Application class.
Can you show an example of this?

The Application class should still be available in .NET Core 3.0, .Net Core 3.1, and .NET 5 and higher.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,386
Location
Chesapeake, VA
Programming Experience
10+
It looks like you already have an old thread about this. Merging threads...
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,921
Location
Sydney, Australia
Programming Experience
10+
Here are some examples I posted elsewhere:
Windows Forms:
private void Form1_Load(object sender, EventArgs e)
{
    Thread.CurrentThread.Name = "UI Thread";
}
 
private void button1_Click(object sender, EventArgs e)
{
    this.ResetTextBoxText();
 
    this.backgroundWorker1.RunWorkerAsync();
}
 
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Thread.CurrentThread.Name = "Worker Thread";
 
    this.ResetTextBoxText();
}
 
private void ResetTextBoxText()
{
    Debug.WriteLine(Thread.CurrentThread.Name, "ResetTextBoxText");
 
    if (this.textBox1.InvokeRequired)
    {
        this.textBox1.Invoke(new MethodInvoker(ResetTextBoxText));
    }
    else
    {
        this.textBox1.ResetText();
    }
}
WPF:
private BackgroundWorker worker = new BackgroundWorker();
 
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Thread.CurrentThread.Name = "UI Thread";
 
    this.worker.DoWork += new DoWorkEventHandler(worker_DoWork);
}
 
private void button1_Click(object sender, RoutedEventArgs e)
{
    this.ResetTextBoxText();
 
    this.worker.RunWorkerAsync();
}
 
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    Thread.CurrentThread.Name = "Worker Thread";
 
    this.ResetTextBoxText();
}
private void ResetTextBoxText()
{
    Debug.WriteLine(Thread.CurrentThread.Name, "ResetTextBoxText");
 
    if (this.textBox1.Dispatcher.Thread == Thread.CurrentThread)
    {
        this.textBox1.Clear();
    }
    else
    {
        this.textBox1.Dispatcher.Invoke(new Action(ResetTextBoxText));
    }
}
SynchronizationContext:
private SynchronizationContext context = SynchronizationContext.Current;

private void Form1_Load(object sender, EventArgs e)
{
    Thread.CurrentThread.Name = "UI Thread";
}

private void Button1_Click(object sender, EventArgs e)
{
    this.context.Send(this.ResetTextBoxText, null);

    this.BackgroundWorker1.RunWorkerAsync();
}

private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Thread.CurrentThread.Name = "Worker Thread";

    this.context.Send(this.ResetTextBoxText, null);
}

private void ResetTextBoxText(object userState)
{
    Debug.WriteLine(Thread.CurrentThread.Name, "ResetTextBoxText");

    this.TextBox1.ResetText();
}
The example using a SynchromizationContext is for WinForms but it works exactly the same way in WPF, i.e. get the Current instance when you create your object on the UI thread and then use that to Send or Post a method to the UI thread synchronously or asynchronously respectively.
 
Top Bottom