我应该在WPF和c#中使用哪种类型/类型的线程用于我的场景...常规线程,后台工作者或线程池?

时间:2012-09-20 19:40:32

标签: c# wpf multithreading backgroundworker threadpool

我在C#和WPF中创建了一个订单管理器应用程序。订单管理器应用程序需要与以完全不同的运输语言编写的运输应用程序来回通信。程序之间的通信方法是一个XML文件,其EnableShipping属性为0或1,以及SQL数据库。

在我的订单管理器应用程序中,我有一个“开始发货”的按钮,并将EnableShipping属性从0更改为1.发货应用程序正在循环并读取此值,开始发送其特定属性与字符串匹配的所有订单,将此属性更改为其他字符串,并将其他属性(Status Changed)标记为1。

在我的订单管理器应用程序中,截至目前,我有一个线程,它不断循环并检查数据库中Status Changed属性为1的订单,对UI进行更改并写回数据库,Status Changed = 0

以下是一些代码,用于显示我的订单管理器应用程序在线程中的作用。

while(true)
        {
            string enabled = null;
            currentInstance = OrderManager.getCurrentInstance();
            SqlCommand command = new SqlCommand("Select OrderNumber, BatchStatus from dbo.Orders where StatusChanged='1'", connection1);
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    Int64 orderNum = (Int64)reader[0];
                    int index = linqForOrderIndex(orderNum);
                    string batchStatus = (string)reader["BatchStatus"];
                    SqlCommand statusChangedFalse = new SqlCommand("Update dbo.orders Set StatusChanged = '0' where OrderNumber = '" + orderNum + "'", connection2);
                    switch (batchStatus)
                    {
                        case "Untouched":
                            currentInstance.Orders[index].batchStatus = "Untouched";
                            break;
                        case "Batch Ready":
                            currentInstance.Orders[index].batchStatus = "Batch Ready";
                            break;
                        case "Shipped":
                            currentInstance.Orders[index].batchStatus = "Shipped";
                            break;
                        case "Error":
                            currentInstance.Orders[index].batchStatus = "Error";
                            break;
                    }
                    statusChangedFalse.ExecuteNonQuery();

                    Thread.Sleep(1000);

                    reader.Close();
                    reader = command.ExecuteReader();
                }

                currentInstance.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                    new Action(
                        delegate()
                        {
                            currentInstance.refreshTreeFilters();
                            currentInstance.refreshOrderCounts();
                            currentInstance.batchReadyView();
                        }
                    )); 
            }
      }

所以,即使您不确切知道代码中发生了什么,您也知道我必须不断检查数据库中的状态更改项,对我的集合以及数据库中的这些项进行处理,更新UI,并不断重复该过程。

起初我认为一个好的老线程会像我的代码现在一样工作,但是当我“做工作”时,UI变得没有响应。我在线查看了一些后台工作者代码,看看是否可能是更好的UI响应能力的一个很好的选择,但不知道这是否是一个很好的解决方案,因为我需要不断继续工作和更新UI。

有什么想法或建议吗?欣赏它...

1 个答案:

答案 0 :(得分:0)

您可以将BackGroundWorker与ReportsProgess一起使用,以将信息发送到UI线程。您可以传递一个对象。同时实施取消,这样您就不会关闭流。

BackgroundWorker.ReportProgress Method

另一种选择是有一种获取SQL通知的方法。

Query Notifications in SQL Server