试图在计时器内读取XML,但它';It’不起作用

本文关键字:It 不起作用 但它 计时器 XML 读取 | 更新日期: 2023-09-27 18:27:36

我想每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)
    {
    }
}

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

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

试图在计时器内读取XML,但它';It’不起作用

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

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

我会像这个一样做

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)
            {
            }
        }
    }
}
​

我也不确定你想做什么,我确信计时器没有触发,因为它在main结束时被删除。它只是一个局部变量。我还发现了一些其他的东西,并试图修复它:

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

希望能有所帮助。。。