RunWorkerCompleted在工作似乎完成之前返回

时间:2015-03-16 14:32:36

标签: c# wpf

我正在使用查询来填充WPF应用程序中的组合框。我弹出一个Xceed busy indicator,然后在所有项目加载到框中之前立即关闭。有没有办法控制这个。我在RunWorkerCompleted方法中有禁用繁忙指示器,但它似乎在完成之前调用它。 这就是我所拥有的:

        private void ItemSearch_Click(object sender, RoutedEventArgs e)
    {
        CboCustomerList.Items.Clear();

        busyIndicator.IsBusy = true;

        BackgroundWorker itemSearchWorker = new BackgroundWorker();
        itemSearchWorker.DoWork += new DoWorkEventHandler(FillCustomers);
        itemSearchWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(itemSearchWorker_Completed);

        itemSearchWorker.RunWorkerAsync();

    }

    private void itemSearchWorker_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
        //busyIndicator.Visibility = System.Windows.Visibility.Hidden;
        busyIndicator.IsBusy = false;
    }

    private void FillCustomers(object sender, DoWorkEventArgs e)
    {


        SqlDataAdapter adapter = new SqlDataAdapter();
        DataSet ds = new DataSet();
        string sql = "Select * from CustTable order by NAME asc";
        string connectionString = Settings.Default.ProdConnectionString;
        SqlConnection connection = new SqlConnection(connectionString);
        SqlCommand SqlCmd = new SqlCommand();
        SqlCmd.CommandType = CommandType.Text;
        SqlCmd.Connection = connection;
        SqlCmd.CommandText = sql;
        SqlDataReader reader = null;
        connection.Open();
        reader = SqlCmd.ExecuteReader();
        List<String> listOfString = new List<string>();
        while (reader.Read())
        {
           listOfString.Add(reader["NAME"].ToString());
        }
        Dispatcher.Invoke((Action)(() =>CboCustomerList.ItemsSource = listOfString));

        connection.Close();


    }

请注意调用前指示器的设置,以及itemSearchWorker_Completed功能中忙指示灯的关闭。 这不应该等到第一次调用整个函数吗?

1 个答案:

答案 0 :(得分:1)

根据MSDN,您永远不应该在Backgroundworker DoWork事件中操作UI对象。

  

您必须小心不要操纵任何用户界面对象   你的DoWork事件处理程序。而是与用户界面进行通信   通过ProgressChanged和RunWorkerCompleted事件。

FillCustomers方法中,我建议您更改此行:

Dispatcher.Invoke((Action)(() =>CboCustomerList.ItemsSource = listOfString));

对此:

e.Result = listOfString;

所以现在完成的徒人变成了:

private void itemSearchWorker_Completed(object sender, RunWorkerCompletedEventArgs e)
{
    CboCustomerList.ItemsSource = e.Result as List<string>; 
    //busyIndicator.Visibility = System.Windows.Visibility.Hidden;
    busyIndicator.IsBusy = false;
}