我应该在WPF和c#中使用哪种类型的线程(我的情况是...常规线程,后台工作程序或线程池)? [英] What type/types of threading should I use in WPF and c# for my scenario... regular threads, background worker, or thread pool?

查看:220
本文介绍了我应该在WPF和c#中使用哪种类型的线程(我的情况是...常规线程,后台工作程序或线程池)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在我的订单管理器应用程序中,我具有一个开始发货"按钮,并将EnableShipping属性从0更改为1.该发货应用程序正在循环并读取此值,开始发货其某些属性与字符串匹配的所有订单,将此属性更改为其他字符串,并将其他属性(状态已更改")标记为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.

有什么想法或建议吗?谢谢...

解决方案

您可以将BackGroundWorker与ReportsProgess一起使用,以将信息发送到UI线程.您可以传递一个对象.此外,请执行取消操作,以免关闭流.

BackgroundWorker.ReportProgress方法

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

SQL Server中的查询通知

I have an order manager application created in C# and WPF. The order manager application needs to communicate back and forth with a shipping application that is written in a completely different shipping language. The method of communication between the programs is an XML file whose EnableShipping attribute is either a 0 or a 1 and a SQL database.

In my order manager application I have button that "Begins shipping" and changes the EnableShipping attribute from a 0 to a 1. The shipping application is looping and reads this value, begins shipping all of the orders whose certain attribute matches a string, changes this attribute to a different string, and marks a different attribute (Status Changed) to 1.

In my order manager application, as of now I have a thread that continually loops and checks the database for orders with a Status Changed attribute of 1, makes the changes to the UI and writes back to the database, Status Changed = 0.

Here is some code to show what my order manager application is doing in the thread.

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

So Even if you don't know exactly what is going on in the code, you know that I have to continuously check the database for status changed items, do work on those items in my collection as well as in the database, update the UI, and keep repeating the process.

At first I thought a good old thread would work like my code is doing now, but the UI becomes unresponsive when I am "doing work". I looked at some background worker code online seeing if maybe that would be a good choice for better UI responsiveness, but didn't know if this is a good solution as I need to continuously keep doing work and updating the UI.

Any thoughts or suggestions? appreciate it...

解决方案

You could use BackGroundWorker with ReportsProgess to send the info to UI thread. You can pass an object. Also implement cancellation so you you don't shut down stream.

BackgroundWorker.ReportProgress Method

The other option is there is a way to get SQL notification.

Query Notifications in SQL Server

这篇关于我应该在WPF和c#中使用哪种类型的线程(我的情况是...常规线程,后台工作程序或线程池)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆