I have an application which has a C# front end (GUI client), and a C++ back end (business logic). The back end is responsible for requesting progress bar functionality and does this by issuing events which the front-end has observer delegates to respond to and act upon. so events are dispatched and responded to in the main thread.
I would like to spawn a second thread to display and update the progress bar, as the main thread is occupied by the back-end doing its thing. While I can show the progress bar window when supposed to, and correctly hide when finished, it will not respond to updates/increments.
ProgressBarWindow
holds the progress bar control (pBar
).
ProgressBarWindow
is owned by progressBarThread
.
public static EventObserver.ProgressBeginEvent pbe = null;
public static EventObserver.ProgressFinishEvent pfe = null;
public static EventObserver.ProgressIncrementEvent pie = null;
public static Thread progressBarThread = null;
static private void InitialiseProgressBarManager()
{
// Setup the progress bar callbacks...
pbe = new EventObserver.ProgressBeginEvent(delegate
(int currentIncrements, int totalIncrements, string message)
{
// Create the thread and progress bar window...
progressBarThread = new Thread(() =>
{
ProgressBarWindow sw = new ProgressBarWindow();
sw.pBar.IsIndeterminate = false;
sw.pBar.Minimum = currentIncrements.Value;
sw.pBar.Maximum = totalIncrements.Value;
sw.pBar.Value = 0;
sw.Show();
pie = new EventObserver.ProgressIncrementEvent(delegate ()
{
sw.pBar.Value++; // The calling thread cannot access this object... see below
});
pfe = new EventObserver.ProgressFinishEvent(delegate ()
{
progressBarThread.Abort();
progressBarThread = null;
});
});
progressBarThread.SetApartmentState(ApartmentState.STA);
progressBarThread.IsBackground = true;
progressBarThread.Start();
});
}
The window shows when expected, and the ProgressIncrementEvent
gets raised correctly (it is owned by the thread), however I get an exception when it tries to access the value.
The calling thread cannot access this object because a different thread owns it.
Do I need a mutex or some other lock? I was hoping the scope of the observer delegate would allow the delegate to have mutable access to the thread local ProgressBarWindow
even though it is being invoked from the main thread?
I'm not a great C# developer and even less so C# threading so I am a bit stuck about what I should be doing here or even if I can achieve this behaviour. Any help or direction to get this working would be appreciated.
P.S I am using WPF with ProgressBarWindow being defined in XAML.