Reputation: 1320
I am quite new with using different threads and using the BackgroundWorker
, so I do not fully understand everything yet. I have posted all the coding that I have from the client side of the program below.
The problem that I have is that even though I use the BackgroundWorker
, I still lose functionality of all of the UI while I load data from my WCF service to my WPF client application. It takes about 2-3 minutes to load the data(about +- 1500 lines of data), so it makes for a really bad user experience.
Is there any obvious thing that I might be missing to get the UI working while the data loads into the datagrid
? Any advice would be appreciated, thank you! :)
Updated Code:
public partial class pgSysproStock : Window
{
public pgSysproStock()
{
InitializeComponent();
SysproStock.WindowState = WindowState.Normal;
dgSysproStock.IsEnabled = false;
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.WorkerReportsProgress = true;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
}
private readonly BackgroundWorker worker = new BackgroundWorker();
private async void worker_DoWork(object sender, DoWorkEventArgs e)
{
using (TruckServiceClient TSC = new TruckServiceClient())
{
List<AllStock> allStock = new List<AllStock>();
this.Dispatcher.Invoke((Action)(() =>
{
prgStockProgress.Visibility = Visibility.Visible;
}));
foreach (var item in await TSC.GetSysproStockAsync())
allStock.Add(new AllStock
{
Id = item.Id,
StockCode = item.StockCode,
Description = item.Description,
ConvFactAltUom = item.ConvFactAltUom,
ConvMulDiv = item.ConvMulDiv,
ConvFactOthUom = item.ConvFactOthUom,
MulDiv = item.MulDiv,
Mass = item.Mass,
Updated_Supplier = item.Updated_Supplier,
CycleCount = item.CycleCount,
ProductClass = item.ProductClass.ToString(),
UnitCost = item.UnitCost,
Discount = item.Discount,
Warehouse = item.Warehouse,
MinimumStock = item.MinimumStock,
MaximumStock = item.MaximumStock,
StockForNow = item.StockForNow,
CoilWidth = item.CoilWidth,
SheetCoilLength = item.SheetCoilLength,
MaterialThickness = item.MaterialThickness
});
e.Result = allStock.ToArray();
}
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.prgStockProgress.Value = e.ProgressPercentage;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
dgSysproStock.ItemsSource = (AllStock[])e.Result;
dgSysproStock.IsEnabled = true;
}
}
EDIT: I've also removed the async
& await
from the method in my coding, but the data still doesn't seem to come through.
I've added a breakpoint here: foreach (var item in await TSC.GetSysproStockAsync())
and I can't get past the TSC.GetSysproStock())
code. Why is it doing this?
Upvotes: 1
Views: 70
Reputation: 10764
Using the async/await correctly:
public pgSysproStock()
{
InitializeComponent();
SysproStock.WindowState = WindowState.Normal;
this.UpdateStockAsync();
}
private async void UpdateStockAsync()
{
dgSysproStock.IsEnabled = false;
using (TruckServiceClient TSC = new TruckServiceClient())
{
var allStock = await TSC.GetSysproStockAsync().ToArray();
dgSysproStock.ItemsSource = allStock.Select(item =>
new AllStock
{
Id = item.Id,
StockCode = item.StockCode,
Description = item.Description,
ConvFactAltUom = item.ConvFactAltUom,
ConvMulDiv = item.ConvMulDiv,
ConvFactOthUom = item.ConvFactOthUom,
MulDiv = item.MulDiv,
Mass = item.Mass,
Updated_Supplier = item.Updated_Supplier,
CycleCount = item.CycleCount,
ProductClass = item.ProductClass.ToString(),
UnitCost = item.UnitCost,
Discount = item.Discount,
Warehouse = item.Warehouse,
MinimumStock = item.MinimumStock,
MaximumStock = item.MaximumStock,
StockForNow = item.StockForNow,
CoilWidth = item.CoilWidth,
SheetCoilLength = item.SheetCoilLength,
MaterialThickness = item.MaterialThickness
}).ToArray();
dgSysproStock.IsEnabled = true;
}
}
Upvotes: 2
Reputation: 10764
This is not how the BackgroundWorker should be used. Try passing the data through to the RunWorkerCompleted event handler and update the UI from there.
Remove this:
this.Dispatcher.Invoke((Action)(() =>
{
dgSysproStock.ItemsSource = (allStock.ToArray());
dgSysproStock.IsEnabled = true;
}));
In the DoWork event handler, set the Result to your data:
e.Result = allStock.ToArray();
Then in the RunWorkerCompleted event handler:
dgSysproStock.ItemsSource = (AllSTock[])e.Result;
dgSysproStock.IsEnabled = true;
Upvotes: 1