学习与BackgroundWorkers合作

时间:2016-09-26 15:37:52

标签: c# wpf backgroundworker

我正在学习使用BackgroundWorker类并创建了一个简单的程序来使用。

我整理了一个非常简单的应用程序。它有两个.xamls,一个是MainWindow,另一个是WorkersRunningUI。 MainWindow只有一个按钮,WorkersRunningUI有一个标签。然后是Worker.cs类,它包含所有BackgroundWorker逻辑。

我的目标: 当我单击MainWindow上的按钮时,我希望隐藏MainWindow并显示WorkersRunningUI。然后,这将启动一个BackgroundWorker,他将进行一些处理(增量 计数器),在计数器递增时更新WorkersRunningUI中的标签,一旦完成就隐藏WorkersRunningUI并再次显示MainWindow。

结果: 当我单击按钮时,看起来UI线程被锁定。我可以看到DoWork方法通过命令行递增计数器,但UI被锁定直到它完成。我的研究表明 使用DoWork内部的UI做任何事情是一个很大的禁忌,你需要使用ProgressChanged进行UI更新。我已经这样做了,所以我不确定UI继续锁定我的原因是什么。我可以看到WorkerRunningUI显示,但它似乎挂起了。

MainWindow.xaml

<Window x:Class="BW_TEST.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Button Content="Second Imp" HorizontalAlignment="Left" Margin="301,199,0,0" VerticalAlignment="Top" Width="75" Click="btn_SecondImpClick"/>
</Grid>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public WorkerRunningUI workerUI;
    public MainWindow()
    {
        InitializeComponent();
    }


    private void btn_SecondImpClick(object sender, RoutedEventArgs e)
    {
        Worker workerObject = new Worker();
        this.Hide(); // hide main application
        workerObject.workerUI.Show();
        workerObject.launchWorker(1);
        workerObject.workerUI.Hide();
        this.Show();
        }
    }
}

WorkerRunningUI.xaml

<Window x:Class="BW_TEST.WorkerRunningUI"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WorkerRunningUI" Height="300" Width="300">
<Grid Margin="0,0,-8,-1" Height="271" VerticalAlignment="Top" HorizontalAlignment="Left" Width="300">
    <Label Name="WorkerLabel" Content="Label" HorizontalAlignment="Left" Margin="89,90,0,0" VerticalAlignment="Top" Width="103"/>
</Grid>

WorkerRunningUI.xaml.cs

public partial class WorkerRunningUI : Window
{
    public WorkerRunningUI()
    {
        InitializeComponent();
    }
}

Worker.cs

// This class is responsible for the BackgroundWorker logic
class Worker
{
    public BackgroundWorker worker;
    public WorkerRunningUI workerUI;

    public Worker()
    {
        this.worker = new BackgroundWorker();
        this.workerUI = new WorkerRunningUI();
        this.worker.DoWork += worker_DoWork;
        this.worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        this.worker.WorkerReportsProgress = true;
        this.worker.ProgressChanged += worker_ProgressChanged;
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Console.WriteLine("Progress Changed: " + e.ProgressPercentage.ToString());
        this.workerUI.WorkerLabel.Content = e.ProgressPercentage.ToString();
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine("RunWorkerCompleted: " + e.Result);
        this.workerUI.Hide(); // hide loading app
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        int value = (int)e.Argument;

        while (value < 1000)
        {
            this.worker.ReportProgress(value);
            value++;
        }

        e.Result = value;
    }

    public void launchWorker(int i)
    {
        this.worker.RunWorkerAsync(i);
    }
}

0 个答案:

没有答案