试图从计时器内的XML读取,但它不起作用

时间:2015-12-19 19:26:52

标签: c# xml timer

我想每5秒打印1到6个数字,并在到达列表末尾时停止计时器。

打印结果:

  

1
  2
  3
  4
  5
  6

代码:

private static void Main(string[] args)
{        
    List<int> l = new List<int>() {1,2,3,4,5,6};
    XElement xdoc = XElement.Load("../../XMLFile1.xml");
    xdoc.Element("num").Value = "0";
    xdoc.Element("max").Value = l.Count.ToString();
    xdoc.Save("../../XMLFile1.xml");
    Timer t = new Timer(printnum, null, 0, 5000);           
}

public static void printnum(Object o)
{
    try
    {
        XElement xdoc = XElement.Load("../../XMLFile1.xml");
        int num = int.Parse(xdoc.Element("num").Value);
        int max = int.Parse(xdoc.Element("max").Value);
        if (num<max)
        {
            Console.WriteLine(num);
            num += 1;
            xdoc.Element("num").Value = num.ToString();
            xdoc.Save("../../XMLFile1.xml");
        }          
    }
    catch (Exception e)
    {

    }
}

这是我的名为XMLFile1.xml的XML文件,num正在运行编号,max是列表最大编号:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <num>0</num>
    <max>0</max>
</root>

3 个答案:

答案 0 :(得分:0)

您的主要问题是您的应用程序在Main方法存在后终止。发生这种情况是因为Timer将在不同的Thread上执行代码。要解决您的问题,只需通过执行类似于从控制台读取一行的内容来暂停主线程:

private static void Main(string[] args)
{        
    List<int> l = new List<int>() {1,2,3,4,5,6};
    XElement xdoc = XElement.Load("../../XMLFile1.xml");
    xdoc.Element("num").Value = "0";
    xdoc.Element("max").Value = l.Count.ToString();
    xdoc.Save("../../XMLFile1.xml");
    Timer t = new Timer(printnum, null, 0, 5000);    

    Console.ReadLine(); //Read a line from the console which forces the main thread to wait
}

但是,您的要求可以在不使用Xml文件的情况下完成,这是一个示例:

private static void Main(string[] args)
{
    int number = 1;

    Timer timer = null;

    timer = new Timer((s) =>
    {
        Console.WriteLine(number++);

        if (number == 7)
            timer.Dispose();

    }, null, 0, 5000);

    Console.ReadLine();
}

甚至更简单,你不需要计时器:

private static void Main(string[] args)
{
    for (int number = 1; number <= 6; number ++)
    {
        Console.WriteLine(number);
        Thread.Sleep(5000);
    }
}

这是另一个异步版本:

private static void Main(string[] args)
{
    Print(1, 6, TimeSpan.FromSeconds(5)); //This doesn't cause the thread to wait

    //Do something else if you want
    Console.ReadLine();
}

private async static Task Print(int from, int to, TimeSpan every)
{
    for (int number = from; number <= to; number ++)
    {
        Console.WriteLine(number);
        await Task.Delay(every);
    }
}

答案 1 :(得分:0)

此外我不确定你要做什么,我确信定时器没有触发,因为它在主要结束时被删除。它只是一个局部变量。我还找到了其他一些东西并尝试解决它:

class Test
{
    Timer timer = new Timer();

    public void DoIt()
    {
        List<int> l = new List<int>() { 1, 2, 3, 4, 5, 6 };
        XElement xdoc = XElement.Load("../../XMLFile1.xml");
        xdoc.Element("num").Value = "0";
        xdoc.Element("max").Value = l.Count.ToString();
        xdoc.Save("../../XMLFile1.xml");

        timer.Interval = 5000;
        timer.Tick += printnum;
        timer.Enabled = true;
    }

    public void printnum(object sender, EventArgs ev)
    {
        try
        {
            XElement xdoc = XElement.Load("../../XMLFile1.xml");
            int num = int.Parse(xdoc.Element("num").Value);
            int max = int.Parse(xdoc.Element("max").Value);
            num += 1;
            Console.WriteLine(num);
            if (num < max)
            {
                xdoc.Element("num").Value = num.ToString();
                xdoc.Save("../../XMLFile1.xml");
            }
            else
            {
                Console.WriteLine("Finish");
                timer.Enabled = false;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

希望有帮助...

答案 2 :(得分:0)

我会这样做

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static AutoResetEvent autoEvent = new AutoResetEvent(false);

        const string FILENAME = @"c:\temp\test.xml";
        private static void Main(string[] args)
        {
            State state = new State();
            state.l  = new List<int>() { 1, 2, 3, 4, 5, 6 };
            state.index = 0;
            state.xdoc = XDocument.Load(FILENAME);
            state.num = state.xdoc.Descendants("num").FirstOrDefault();
            state.xdoc.Descendants("max").FirstOrDefault().Value = state.l.LastOrDefault().ToString();
            Timer t = new Timer(printnum, state, 0, 5000);
            autoEvent.WaitOne();
            t.Dispose();

        }
        public class State
        {
            public XElement num { get; set; }
            public XDocument xdoc { get; set; }
            public List<int> l { get; set; }
            public int index { get; set; }
        }

        public static void printnum(Object o)
        {
            State state = o as State;
            try
            {
                int num = state.l[state.index++];
                Console.WriteLine(num);
                state.num.Value = num.ToString();
                state.xdoc.Save(FILENAME);
                if (state.index >= state.l.Count)
                {
                    autoEvent.Set();
                }
            }
            catch (Exception e)
            {

            }
        }
    }
}
​