使用后台工作程序时丢失UI功能

时间:2015-08-05 09:44:06

标签: c# wpf multithreading wcf backgroundworker

我使用不同的线程并使用BackgroundWorker时很新,所以我还没有完全理解所有内容。我已经在下面的程序的客户端发布了我的所有编码。

我遇到的问题 即使我使用BackgroundWorker,我仍然会在从我加载数据时失去所有用户界面的功能WCF服务到我的WPF客户端应用程序。加载数据大约需要2-3分钟(约+ - 1500行数据),因此会造成非常糟糕的用户体验。

当数据加载到datagrid时,是否有任何显而易见的事情可能会让UI失效?任何建议将不胜感激,谢谢! :)

更新代码:

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;
    }
}

编辑:我还删除了async&amp; await来自我编码中的方法,但数据似乎仍未通过。

我在这里添加了一个断点foreach (var item in await TSC.GetSysproStockAsync()),我无法通过TSC.GetSysproStock())代码。为什么要这样做?

2 个答案:

答案 0 :(得分:2)

正确使用async / await:

    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;
    }
}

答案 1 :(得分:1)

这不是应该如何使用BackgroundWorker。尝试将数据传递到RunWorkerCompleted事件处理程序并从那里更新UI。

删除它:

this.Dispatcher.Invoke((Action)(() =>
{
    dgSysproStock.ItemsSource = (allStock.ToArray());
    dgSysproStock.IsEnabled = true;
}));

在DoWork事件处理程序中,将Result设置为您的数据:

e.Result = allStock.ToArray();

然后在RunWorkerCompleted事件处理程序中:

dgSysproStock.ItemsSource = (AllSTock[])e.Result;
dgSysproStock.IsEnabled = true;