C# 如何在wpf中同步多个后台工作类?

C# 如何在wpf中同步多个后台工作类?,c#,wpf,winforms,C#,Wpf,Winforms,我已经实现了类似于下面示例的后台工作程序类,我希望在每次后台工作程序完成时更新我的UI for (int i = 1; i < 10; i++) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(Worker_DoWork);

我已经实现了类似于下面示例的后台工作程序类,我希望在每次后台工作程序完成时更新我的UI

          for (int i = 1; i < 10; i++)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
                worker.RunWorkerAsync(i);

                while (worker.IsBusy == true)
                {
                   Thread.Sleep(100);
                }
            }
for(int i=1;i<10;i++)
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(worker\u RunWorkerCompleted);
worker.RunWorkerAsync(i);
while(worker.IsBusy==true)
{
睡眠(100);
}
}
Worker\u DoWork return datarow和Worker\u RunWorkerCompleted正在将返回的结果添加到数据网格中。但是函数永远不会在Worker\u runworker中以正确的顺序完成。我怎样才能解决这个问题

编辑:

为了清楚起见,我正在更新更多细节

 <my:DataGrid x:Name="theGrid" RowHeight="30" ItemsSource="{Binding Category}" AutoGenerateColumns="True" HeadersVisibility="All" Margin="235,96.5,84,65.5">
            <my:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <Expander>
                        <my:DataGrid Height="300" ItemsSource="{Binding Products}" AutoGenerateColumns="True" HeadersVisibility="Column"> </my:DataGrid>
                    </Expander>
                </DataTemplate>
            </my:DataGrid.RowDetailsTemplate>
        </my:DataGrid>


    //List of objects
    List<Category> Categories = new List<Category>();

    private void button1_Click(object sender, RoutedEventArgs e)
    {      
        for (int i = 1; i < 10; i++)
        {
            BackgroundWorker worker = new BackgroundWorker();

            worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
            worker.RunWorkerAsync(i);

            while (worker.IsBusy == true)
            {
                Thread.Sleep(100);
            }
        }
    }

    void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        long i = Convert.ToInt64(e.Argument);
        Category cat = new Category { CategoryID = i, Name = "Category" + i };
        cat.Products = new List<Product>();

        for (long j = 1; j < 10; j++)
        {
            Product p = new Product { ProductID = (i * j), Name = "Product " + (i * j).ToString() };
            cat.Products.Add(p);
        }

        e.Result = cat;
    }

    void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Category cat = ((Category)e.Result);
        Categories.Add(cat);
        theGrid.ItemsSource = Categories;
    }
}

public class Product
{
    public long ProductID { get; set; }
    public string Name { get; set; }
}

public class Category
{
    public long CategoryID { get; set; }
    public string Name { get; set; }
    public List<Product> Products { get; set; }
}

//对象列表
列表类别=新列表();
私有无效按钮1\u单击(对象发送者,路由目标)
{      
对于(int i=1;i<10;i++)
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(worker\u RunWorkerCompleted);
worker.RunWorkerAsync(i);
while(worker.IsBusy==true)
{
睡眠(100);
}
}
}
无效工作线程(对象发送器,工作线程目标)
{
长i=Convert.ToInt64(即参数);
类别cat=新类别{CategoryID=i,Name=“Category”+i};
类别产品=新列表();
对于(长j=1;j<10;j++)
{
productp=新产品{ProductID=(i*j),Name=“Product”+(i*j).ToString()};
类别产品添加(p);
}
e、 结果=cat;
}
void Worker\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
类别类别=((类别)e.结果);
类别。添加(cat);
grid.ItemsSource=类别;
}
}
公共类产品
{
公共长ProductID{get;set;}
公共字符串名称{get;set;}
}
公共类类别
{
公共长类别ID{get;set;}
公共字符串名称{get;set;}
公共列表产品{get;set;}
}

您仍在阻止UI线程-在所有后台工作人员完成之前,它无法处理事件。这与
BackgroundWorker
的要点背道而驰。你应该开始,让他们结束。如果您需要在它们完成后进行其他更改,您应该在
RunWorkerCompleted
的处理程序中进行更改-可能会记录有多少个已完成(如果并行启动),或者如果要串联运行,则启动一个新的,直到您运行了所有要运行的线程。

您仍在阻塞UI线程-在所有后台工作人员完成之前,它将无法处理事件。这与
BackgroundWorker
的要点背道而驰。你应该开始,让他们结束。如果您需要在它们完成后进行其他更改,您应该在
RunWorkerCompleted
的处理程序中进行更改-可能会记录有多少个已完成(如果并行启动),或者如果要串联运行,则启动一个新的,在运行完所有要运行的线程之前。

使用后台工作程序时,主要目的是避免阻塞/冻结UI线程。如果Do_Work方法需要很长时间,则尝试在后台工作程序上更改Progress_事件,并从该方法更新UI上的进度。仅当后台工作人员的关联任务完成时,才会调用worker_Completed。您需要从Do_Work中引发其间的Progress Changed事件以更新进度

与进度更改事件关联的某些代码:

worker.WorkerReportsProgress = true;
worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged); 

使用后台工作程序时,主要目的是避免阻塞/冻结UI线程。如果Do_Work方法需要很长时间,则尝试在后台工作程序上更改Progress_事件,并从该方法更新UI上的进度。仅当后台工作人员的关联任务完成时,才会调用worker_Completed。您需要从Do_Work中引发其间的Progress Changed事件以更新进度

与进度更改事件关联的某些代码:

worker.WorkerReportsProgress = true;
worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged); 

不清楚-您编写的代码是否在UI线程中运行?您所说的“未按正确顺序到达”是什么意思?我认为他的意思是,执行第一个BW和第二个BW之后,不能保证first的结果在这一秒之前出现。@jonsket yes代码正在UI线程中运行。@MartinMoser在我的代码中,do worker工作正常,然后在while循环中冻结代码。不清楚-您编写的代码是否在UI线程中运行?您所说的“未按正确顺序到达”是什么意思我想他的意思是,执行第一个BW和第二个BW之后,不能保证第一个BW的结果在第二个BW之前。@Jonsket yes代码正在UI线程中运行。@MartinMoser在我的代码中,do worker工作正常,然后在while循环中冻结代码。