【问题标题】:Windows Server 2012 System.IndexOutOfRangeExceptionWindows Server 2012 System.IndexOutOfRangeException
【发布时间】:2013-03-11 16:45:11
【问题描述】:

我已经编写了一个服务,它在我的计算机上运行良好,但是当我将它移到应该运行它的服务器上时,它会吐出 System.IndexOutOfRangeException 每当它像它应该的那样读取/写入文件时也。我只是觉得它只在服务器上执行此操作很奇怪,而且我不知道它们与我的计算机的工作方式有何不同,因此将不胜感激。

描述:进程因未处理的异常而终止。 异常信息:System.IndexOutOfRangeException 堆: 在 emlService.emlService.runProc() 在 System.Threading.ThreadHelper.ThreadStart_Context(System.Object) 在 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object,布尔) 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object,布尔) 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object) 在 System.Threading.ThreadHelper.ThreadStart()

代码

public partial class emlService : ServiceBase
{
    Boolean _isRunning;

    public emlService()
    {
        InitializeComponent();
        if (!System.Diagnostics.EventLog.SourceExists("emlServiceSource"))
        {
            System.Diagnostics.EventLog.CreateEventSource(
                "emlServiceSource", "emlServiceLog");
        }
        eventLog1.Source = "emlSerivceSource";
        eventLog1.Log = "emlServiceLog";
    }

    protected override void OnStart(string[] args)
    {
        eventLog1.WriteEntry("In OnStart");
        Thread NewThread = new Thread(new ThreadStart(runProc));
        _isRunning = true;
        //Creates bool to start thread loop
        if (_isRunning)
        {
            NewThread.Start();
        }
    }

    protected override void OnStop()
    {
        eventLog1.WriteEntry("In OnStop");
        _isRunning = false;             
    }

    protected override void OnContinue()
    {            
    }

    public void runProc()
    {         

        //Directory of the drop location
        string tempDrop = ConfigurationSettings.AppSettings["conf_drop"];
        DirectoryInfo drop = new DirectoryInfo(tempDrop);

        //Directory of the pickup location
        string tempPickup = ConfigurationSettings.AppSettings["conf_pickup"];
        string destpath = tempPickup;

        //Inits ParserCommands and DropDirectory object
        ParserCommands parserObject = new ParserCommands();

        //Inits array to hold number of messages in drop location
        FileInfo[] listfiles;

        //Inits CFG
        string conf_mailsender = ConfigurationSettings.AppSettings["conf_mailsender"];
        string conf_rcpt = ConfigurationSettings.AppSettings["conf_rcpt"];
        string conf_username_and_password = ConfigurationSettings.AppSettings["conf_username_and_password"];
        string conf_sender = ConfigurationSettings.AppSettings["conf_sender"];
        string conf_raport = ConfigurationSettings.AppSettings["conf_raport"];

        //Loop that never ends
        while (true) 
        {
            //Reduces load on machine
            Thread.Sleep(1000);

            //Checks if there is a message waiting to be processed and begins processing if so
            listfiles = drop.GetFiles();
            if (listfiles.Length >= 1)
            {
                for (int j = 0; j <= (listfiles.Length - 1); j++)
                {
                    //Gives it time to breathe
                    Thread.Sleep(250);

                    try
                    {
                        //Gets each line of the original .eml into a string array
                        var lines = File.ReadAllLines(listfiles[j].FullName);
                        string[] linestring = lines.Select(c => c.ToString()).ToArray();

                        //Seperates start of email from the rest and decode parameter_content
                        string parameter_to = parserObject.getReciever(linestring[12]);
                        string parameter_content = parserObject.DecodeFrom64(linestring[17]);

                        //Creates string ready for base64 encode
                        string encode = "from=" + conf_sender + "&to=" + parameter_to + "&raport=" + conf_raport + "&message=" + parameter_content;

                        //Opens up steam and writer in the new dest, creates new .eml file
                        using (FileStream fs = new FileStream(destpath + listfiles[j].Name, FileMode.CreateNew))
                        using (StreamWriter writer = new StreamWriter(fs))
                        {

                            //Writes all .eml content into buffer
                            writer.WriteLine("x-sender: " + conf_mailsender);
                            writer.WriteLine("x-receiver: " + conf_rcpt);
                            writer.WriteLine(linestring[2]);
                            writer.WriteLine(linestring[3]);
                            writer.WriteLine(linestring[4]);
                            writer.WriteLine(linestring[5]);
                            writer.WriteLine(linestring[6]);
                            writer.WriteLine(linestring[7]);
                            writer.WriteLine(linestring[8]);
                            writer.WriteLine("From: " + conf_mailsender);
                            writer.WriteLine(linestring[10]);
                            writer.WriteLine("Reply-To: " + conf_mailsender);
                            writer.WriteLine("To: " + conf_rcpt);
                            writer.WriteLine("Subject: " + conf_username_and_password);
                            writer.WriteLine("Return-Path: " + conf_mailsender);
                            writer.WriteLine(linestring[15]);
                            writer.WriteLine();

                            //Writes encoded string into buffer
                            writer.WriteLine(parserObject.EncodeTo64(encode));

                            //Writes buffer into .eml file
                            writer.Flush();
                        }

                        lines = null;
                    }
                        catch (System.IO.IOException e)
                    {
                        Console.WriteLine("no");

                    }

                    //Deletes the file
                    File.Delete(listfiles[j].FullName);
                }

                //Sets the number of files needing sent to 0
                listfiles = null;
            }
        }
    }
}

【问题讨论】:

    标签: c# windows service out


    【解决方案1】:

    据我所知,您没有在任何地方检查linestring 的长度。我不能肯定地说,因为您没有提供足够的信息,但我会认为 linestring.Length 小于 17,导致 parserObject.DecodeFrom64(linestring[17]); 抛出异常。也可能是linestring.Length 小于 12,它是之前的那一行。

    要解决这个问题,您应该检查linestring 的长度并适当地处理结果。

    string[] linestring = lines.Select(c => c.ToString()).ToArray();
    if(linestring.Length <= 17)
    {
        //handle malformed file
    }
    else
    {
        //complete the processing
    }
    

    与您的问题无关,但我很好奇您认为lines.Select(c =&gt; c.ToString() 的效果是什么。 File.ReadAllLines() 已经返回一个字符串数组,所以 `Select(c => c.ToString()) 是多余的。

    【讨论】:

    • 我用另一种方式解决了这个问题,但我一定会将此代码添加到我的服务中,谢谢!至于 ReadAllLines,我不知道它是这样工作的,我终于让服务正常工作,并将在接下来的几天内对其进行优化,我一定会在那里进行更改,谢谢!
    【解决方案2】:

    在您正在阅读的一行中,线串不是您期望的长度。

    你确定这永远不会失败吗?

    linestring[17]
    

    如果您的文件中有一个空行怎么办?

    【讨论】:

    • 啊,谢谢,这促使我查看文件,它们实际上已损坏,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2017-03-22
    • 2014-02-05
    相关资源
    最近更新 更多