【问题标题】:threading for a windows serviceWindows 服务的线程
【发布时间】:2013-02-13 08:44:50
【问题描述】:

我做了一个读取 xml 的服务。在 xml 我有输入目录和输出目录。该服务选择输入目录中的文件并重命名它们并将它们移动到输出目录。我想在服务中实现线程。我希望它在一个线程中选择一个 xml 节点,在另一个线程中选择另一个节点。或者,如果不考虑节点,一个线程选择要执行的前 10 个操作,然后选择下一个要执行的 10 个操作,等等,这甚至会很好。这样所有节点都以并行方式处理。谁可以帮我这个事?我尝试阅读一些线程教程,但无法通过它们获得太多。服务代码如下:

XmlDocument doc = new XmlDocument();
            doc.Load("Data.xml");
            int count = doc.SelectNodes("Data/DataClass").Count;
            for (int i = 1; i < count; i++)
            {
                string xpath = "/Data/DataClass[" + i + "]";
                XmlNode node = doc.SelectSingleNode(xpath);
                XmlNodeList subnode = node.ChildNodes;
                string pathO = "";
                string pathI = subnode[0].InnerText;
                string prefix = subnode[2].InnerText;
                string freq = subnode[3].InnerText;
                string[] filenames = Directory.GetFiles(pathI);
                node.ParentNode.RemoveChild(doc.SelectSingleNode(xpath));
                doc.Save("Data.xml");

                foreach (string filename in filenames)
                {
                    pathO = subnode[1].InnerText;
                    pathO = pathO + "\\" + prefix;
                    string fname = Path.GetFileName(filename);
                    pathO = pathO + fname;
                    System.IO.File.Move(filename, pathO);

                }
            } 

【问题讨论】:

  • 你应该放弃思考你需要多少线程的想法,让 Imran 来帮助你

标签: c# multithreading windows-services


【解决方案1】:

使用 Parallel.For 或 Parallel.ForEach,检查以下代码,它很简单,我已在此处修改了您的代码,因此请使用 VS 进行检查(根据您的要求可能会有小的更改)。

XmlDocument doc = new XmlDocument();
doc.Load("Data.xml");
int count = doc.SelectNodes("Data/DataClass").Count;
Parallel.For(0,doc.SelectNodes("Data/DataClass").Count-1,i =>
{
    XmlNode node = doc.SelectNodes("Data/DataClass")[i];
    XmlNodeList subnode = node.ChildNodes;
    string pathO = "";
    string pathI = subnode[0].InnerText;
    string prefix = subnode[2].InnerText;
    string freq = subnode[3].InnerText;
    string[] filenames = Directory.GetFiles(pathI);
    doc.Save("Data.xml");
    foreach (var filename in filenames)
    {
        pathO = subnode[1].InnerText;
        pathO = pathO + "\\" + prefix;
        string fname = Path.GetFileName(filename);
        pathO = pathO + fname;
        System.IO.File.Move(filename, pathO);
    }
}
);

不要删除并行循环内的子节点,所以我删除了以下行 node.ParentNode.RemoveChild(node);

了解更多关于 Task Parallel Liberary (http://msdn.microsoft.com/en-us/library/dd537608.aspx) 的并行处理功能。

【讨论】:

  • 您应用并行 foreach 的文件名部分用于目录中的各种文件。我正在尝试在 xml 节点上实现它(即在各种目录上)。我尝试在上面的 for 循环中执行此操作,但似乎无法正常工作。
  • 我完全尝试过您在答案中发布的内容,但是当我很确定有数据时,它只是为 xml 中的最后一个节点提供对象引用 null 答案。而且有时它只移动指定目录中的一半文件,而剩下的文件很少。所以简而言之不能正常工作。
  • 尝试防止在并行循环中删除子节点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
相关资源
最近更新 更多