Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用后台工作程序时丢失UI功能_C#_Wpf_Multithreading_Wcf_Backgroundworker - Fatal编程技术网

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

C# 使用后台工作程序时丢失UI功能,c#,wpf,multithreading,wcf,backgroundworker,C#,Wpf,Multithreading,Wcf,Backgroundworker,我对使用不同的线程和BackgroundWorker非常陌生,因此我还没有完全理解所有内容。我已经在下面的程序客户端发布了所有代码 我遇到的问题是,即使我使用了BackgroundWorker,当我将数据从WCF服务加载到WPF客户端应用程序时,仍然会丢失所有UI的功能。加载数据(大约+-1500行数据)大约需要2-3分钟,因此会造成非常糟糕的用户体验 当数据加载到datagrid中时,我是否缺少任何明显的东西来让UI工作?任何建议都将不胜感激,谢谢!:) 更新代码: public partia

我对使用不同的线程和
BackgroundWorker
非常陌生,因此我还没有完全理解所有内容。我已经在下面的程序客户端发布了所有代码

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

当数据加载到
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;
    }
}
公共部分类pgSysproStock:Window
{
公共pgSysproStock()
{
初始化组件();
SysproStock.WindowState=WindowState.Normal;
dgSysproStock.IsEnabled=false;
worker.DoWork+=worker\u DoWork;
worker.RunWorkerCompleted+=worker\u RunWorkerCompleted;
worker.WorkerReportsProgress=true;
worker.ProgressChanged+=worker\u ProgressChanged;
worker.RunWorkerAsync();
}
private readonly BackgroundWorker worker=new BackgroundWorker();
私有异步void worker_DoWork(对象发送方,DoWorkEventArgs e)
{
使用(TruckServiceClient TSC=new TruckServiceClient())
{
List allStock=新列表();
this.Dispatcher.Invoke((操作)(()=>
{
prgStockProgress.Visibility=可见性.Visibility;
}));
foreach(wait TSC.GetSysproStockAsync()中的变量项)
allStock.Add(新的allStock)
{
Id=项目Id,
StockCode=item.StockCode,
描述=项目。描述,
ConvFactAltUom=item.ConvFactAltUom,
ConvMulDiv=item.ConvMulDiv,
convfactothoom=item.convfactothoom,
MulDiv=item.MulDiv,
质量=项目质量,
更新的供应商=物料。更新的供应商,
CycleCount=item.CycleCount,
ProductClass=item.ProductClass.ToString(),
单位成本=项目。单位成本,
折扣=物品。折扣,
仓库=项目。仓库,
最小库存=物料。最小库存,
MaximumStock=item.MaximumStock,
StockForNow=item.StockForNow,
CoilWidth=item.CoilWidth,
SheetCoillLength=项目。SheetCoillLength,
材料厚度=项目。材料厚度
});
e、 结果=allStock.ToArray();
}
}
私有void worker\u ProgressChanged(对象发送方,ProgressChangedEventArgs e)
{
this.prgStockProgress.Value=e.ProgressPercentage;
}
私有void worker\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{            
dgSysproStock.ItemsSource=(AllStock[])e.Result;
dgSysproStock.IsEnabled=true;
}
}
EDIT:我还从编码中的方法中删除了
async
&
wait
,但数据似乎仍然没有通过


我在这里添加了一个断点:
foreach(wait TSC.GetSysproStockAsync()中的var项)
,我无法通过
TSC.GetSysproStock())
code。为什么要这样做?

这不是BackgroundWorker的使用方式。尝试将数据传递到RunWorkerCompleted事件处理程序,并从那里更新UI

删除此项:

this.Dispatcher.Invoke((Action)(() =>
{
    dgSysproStock.ItemsSource = (allStock.ToArray());
    dgSysproStock.IsEnabled = true;
}));
在DoWork事件处理程序中,将结果设置为数据:

e.Result = allStock.ToArray();
然后在RunWorkerCompleted事件处理程序中:

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

正确使用异步/等待:

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

这是阻止UI的操作:
dgSysproStock.ItemsSource=(allStock.ToArray())。不能将异步/等待与后台工作程序混合使用<代码>工作者工作
不能是异步的。我想说的是,扔掉BGW,单独使用async await。乍一看,在BackgroundWorker中使用async/await似乎是错误的。@Sriram Sakthivel-谢谢您的评论!:)如果我删除
BackgroundWorker
我将无法使用我的UI,因为当我从WCF服务加载数据时,它将被禁用。如果您正确使用async/Wait,则不需要BackgroundWorker。await关键字会导致方法执行在多个线程之间分割,而方法的其余部分则充当回调。感谢您的回答和努力D我已经按照您的建议更新了代码,现在我可以使用我的所有UI元素(谢谢),但由于某些原因,数据似乎没有加载到我的datagrid中。问题可能出在
e.Result=allStock.ToArray()在我的嫁妆活动结束时?再次感谢你的第二个答案,格伦。数据加载与您提供的新编码很好,但我回到原点,所有UI仍然处于禁用/无响应状态:(但感谢您尝试帮助我。)在我做了一些研究之后,我会去问一个关于这个的新问题。我认为问题可能是GetSysproStockAsync使用yield关键字返回迭代器。尝试添加我更新的答案中的.ToArray(),看看这是否有帮助。嗨,格伦
var allStock=wait TSC.GetSysproStockAsync().ToArray()告诉我错误:不包含“ToArray”的定义,也没有扩展方法“ToArray”。您可能需要将“using System.Linq;”添加到代码文件中