且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我应该在WPF和c#中使用哪种类型的线程(我的情况是...常规线程,后台工作程序或线程池)?

更新时间:2023-11-13 17:09:10

您可以将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