简体   繁体   English

将记录插入到SQL Server CE数据库移动到另一个线程? C#Compact Framework 3.5

[英]Move record insert to SQL Server CE database into another thread? C# Compact Framework 3.5

I had some trouble trying to place piece of code into another thread to increase performance. 我在尝试将一段代码放入另一个线程以提高性能时遇到了一些麻烦。

I have following code below (with thread additions with comments), where I parse large XML file (final goal 100,000 rows) and then write it to a SQL Server CE 3.5 database file ( .sdf ) using record and insert ( SqlCeResultSet/SqlCeUpdatableRecord ). 我在下面有以下代码(带有注释的线程添加),其中我解析大型XML文件(最终目标100,000行),然后使用记录和插入( SqlCeResultSet/SqlCeUpdatableRecord )将其写入SQL Server CE 3.5数据库文件( .sdf ) 。

Two lines of code in if statement inside the while loop, while循环中if语句中的两行代码,

xElem = (XElement)XNode.ReadFrom(xmlTextReader);

and

rs.Insert(record);

take about the same amount of time to execute. 花费大约相同的时间来执行。 I was thinking to run rs.Insert(record); 我想要运行rs.Insert(record); while I am parsing the next line of xml file. 而我正在解析下一行的xml文件。 However, I still was unable to do it using either Thread or ThreadPool. 但是,我仍然无法使用Thread或ThreadPool来完成它。

I have to make sure that the record that I pass to thread is not changed until I finish executing rs.Insert(record); 我必须确保传递给线程的记录在我执行rs.Insert(record);之前不会更改rs.Insert(record); in existing thread. 在现有的线程中。 Thus, I tried to place thread.Join() before writing new record ( record.SetValue(i, values[i]); ), but I still get conflict when I try to run the program - program crashes with bunch of errors due to trying to write identical row several times (especially for index). 因此,我尝试在写入新记录之前放置thread.Join()( record.SetValue(i, values[i]); ),但是当我尝试运行程序时仍然会出现冲突 - 程序崩溃时出现大量错误尝试多次写入相同的行(特别是索引)。

Can anyone help me with some advise? 任何人都可以帮我提一些建议吗? How can I move rs.Insert(record); 我怎样才能移动rs.Insert(record); into another thread to increase performance? 进入另一个线程来提高性能?

XmlTextReader xmlTextReader = new XmlTextReader(modFunctions.InFName);
XElement xElem = new XElement("item");

using (SqlCeConnection cn = new SqlCeConnection(connectionString))
{
    if (cn.State == ConnectionState.Closed)
        cn.Open();

    using (SqlCeCommand cmd = new SqlCeCommand())
    {
        cmd.Connection = cn;
        cmd.CommandText = "item";
        cmd.CommandType = CommandType.TableDirect;

        using (SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable))
        {
            SqlCeUpdatableRecord record = rs.CreateRecord();

            // Thread code addition
            Thread t = new Thread(new ThreadStart(() => rs.Insert(record));

            while (xmlTextReader.Read())
            {
                if (xmlTextReader.NodeType == XmlNodeType.Element &&
                    xmlTextReader.LocalName == "item" &&
                    xmlTextReader.IsStartElement() == true)
                {
                    xElem = (XElement)XNode.ReadFrom(xmlTextReader);

                    values[0] = (string)xElem.Element("Index"); // 0
                    values[1] = (string)xElem.Element("Name"); // 1
                    ~~~
                    values[13] = (string)xElem.Element("Notes"); // 13

                    // Thread code addition -- Wait until previous thread finishes
                    if (ThreadStartedS == 1)
                    {
                        t.Join()
                    }

                    // SetValues to record
                    for (int i = 0; i < values.Length; i++)
                    {
                        record.SetValue(i, values[i]); // 0 to 13
                    }

                    // Thread code addition -- Start thread to execute rs.Insert(record)
                    ThreadStartedS = 1;
                    t.Start();

                    // Original code without threads
                    // Insert Record
                    //rs.Insert(record);
                }
            }
        }
    }
}

If all of your processing is going to be done on the device (reading from the XML file on the device then parsing the data on the device), then you will see no performance increase from threading your work. 如果要在设备上完成所有处理(从设备上的XML文件读取然后解析设备上的数据),那么您将看到线程化工作没有性能提升。

These Windows Mobile devices only have a single processor, so for them to multithread means one process works for a while, then another process works for a while. 这些Windows Mobile设备只有一个处理器,因此对于它们来说,多线程意味着一个进程可以工作一段时间,然后另一个进程可以工作一段时间。 You will never have simultaneous processes running at the same time. 您永远不会同时运行同时进程。

On the other hand, if the data from your XML file were located on a remote server, you could call the data in chunks. 另一方面,如果XML文件中的数据位于远程服务器上,则可以以块的形式调用数据。 As a chunk arrives, you could process that data in another thread while waiting on the next chunk of data to arrive in the main thread. 当一个块到达时,您可以在另一个线程中处理该数据,同时等待下一个数据块到达主线程。

If all of this work is being done on one device, you will not have good luck with multithreading. 如果所有这些工作都在一台设备上完成,那么多线程就不会有好运。

You can still display a progress bar (from 0 to NumberOfRecords) with a cancel button so the person waiting for the data collection to complete does not go insane with anticipation. 您仍然可以使用取消按钮显示进度条(从0到NumberOfRecords),以便等待数据收集完成的人不会因预期而疯狂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM