Reputation: 16028
I have a progress bar which is bound to the "CurrProgress" and "Total" fields as follows:
<ProgressBar Height="29" HorizontalAlignment="Left" Margin="12,32,0,0" Name="pbSendingData" VerticalAlignment="Top" Width="346"">
<ProgressBar.Value>
<Binding ElementName="this" Path="CurrProgress" />
</ProgressBar.Value>
<ProgressBar.Maximum>
<Binding ElementName="this" Path="Total" />
</ProgressBar.Maximum>
</ProgressBar>
I also have a "Worker thread" that is doing the heavy lifting while trying to keep the UI responsive:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
const int sizeOfPacket = 30;
Total = allEntries.Count();
var arrayOfEntries = Split(allEntries, sizeOfPacket); //Split array into small arrays
//Send parts to server separately:
foreach (var entries in arrayOfEntries)
{
svc.ProcessPMData(Globals.username, Globals.password, entries.ToArray());
CurrProgress += sizeOfPacket;
Thread.Sleep(100);
}
Thread.Sleep(100);
}
I have ensured that the "Total" and "CurrProgress" dependency properties are thread safe (though I may have not done it correctly):
//Dependency properties:
public int CurrProgress
{
get
{
return (int)this.Dispatcher.Invoke(
DispatcherPriority.Background,
(DispatcherOperationCallback)delegate
{
return GetValue(CurrProgressProperty);
}, CurrProgressProperty);
}
set
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
(SendOrPostCallback)delegate { SetValue(CurrProgressProperty, value); },
value);
}
}
public static readonly DependencyProperty CurrProgressProperty =
DependencyProperty.Register("CurrProgress", typeof(int), typeof(DataSender), new PropertyMetadata(0));
public int Total
{
get
{
return (int)this.Dispatcher.Invoke(
DispatcherPriority.Background,
(DispatcherOperationCallback)delegate
{
return GetValue(TotalProperty);
}, TotalProperty);
}
set
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
(SendOrPostCallback)delegate { SetValue(TotalProperty, value); },
value);
}
}
public static readonly DependencyProperty TotalProperty =
DependencyProperty.Register("Total", typeof(int), typeof(DataSender), new PropertyMetadata(0));
When trying to debug, I first tried to check what was the value of the progress bar from the immediate window:
pbSendingData.Value
I was greeted with this error message...
The error made sense, so I tried another way:
this.Dispatcher.Invoke((Action)(() => { MessageBox.Show(pbSendingData.Minimum); }));
At this point I discovered the immediate window does not support lambda expressions.
The watch window was also unhelpful:
While debugging, I want to get the value of a UI components from the immediate/watch window from a different thread. Is this possible? As a sidenote, if there is anything scandalous in my code, I'm open to suggestions. I'm a bit new to WPF.
Upvotes: 2
Views: 143
Reputation: 1411
What element is this "this" element you are referring to in the Bindings of the progress bar properties?
Most code I see uses the dispatcher and delegates from the worker thread and not within the property getters/setters as this might result in some ugly race conditions and deadlocks or similar nasty stuff.
The "DoWork" method seems to belong to a BackGroundWorker class. Why not using the "ReportProgress" feature? It includes thread synchronization...
Upvotes: 1