如何处理Console输出到网络文件的间歇性错误

时间:2015-06-13 21:03:03

标签: .net network-programming console-application

我编写了一个控制台应用程序,通常通过任务计划程序运行,没有用户。如果合适,它会将控制台输出重定向到恰好位于网络上的文件(名称中包含app-start timestamp)。

我见过几个案例 - 它们很少见 - 似乎文件内容过早结束(也就是说,程序生成的后续消息不存在)。第三方日志记录工具(Gibraltar Loupe)的输出向我显示,如果网络故障导致输出文件暂时不可用,则调用Console.WriteLine可能会失败,从而导致未处理的异常。

(曾经,普通应用程序的正常异常处理 - 有点显着 - 能够编写有关由于“指定的网络名称不再可用”而导致Console.WriteLine失败时导致的未处理异常的消息 - 一定是一个非常暂时的故障!)

我想不出一种方法,除了用调用我自己的东西来替换对Console.WriteLine的所有调用来捕获这些错误,等待网络再次可用,然后再次尝试。 (或者可能它会将输出重定向到本地文件以进行剩余的运行,但如果网络不可用,其他事情可能会失败。)

在具有数百个应用程序的应用程序中替换对Console.WriteLine的所有调用将导致主要的源代码更改爆炸,从而强制更改几个月内未更改的文件。我有选择吗?

是否有人对如何处理此问题有不同的建议(除了从项目开头抽象出Console.WriteLine)?

感谢您提出任何建议。

2 个答案:

答案 0 :(得分:4)

尝试解决软件中的片状硬件问题并不是最好的主意。但请考虑:

  • 重定向到本地文件,使用其他计划任务移动文件。
  • 编写一个使用Process.Start()启动此应用程序的小应用程序。并使用Process.ExitCode来查看它的表现。如有必要,它可以多次重启应用程序,在每次尝试之间延迟更长时间。
  • 使用您自己的TextWriter派生类重新分配Console.Error和Console.Out。覆盖Write(char)并调用原始的Error / Out.Write(char)方法,包含在try / catch中。尝试多次失败,在尝试之间延迟更长时间。

你可能认为最后一个很有吸引力。示例代码:

using System.IO;

class MyWriter : TextWriter {
    private TextWriter writer;
    public MyWriter(TextWriter writer) { this.writer = writer; }
    public override Encoding Encoding { get { return writer.Encoding; } }

    public override void Write(char value) {
        for (int delay = 1; ; delay *= 2) {
            try { writer.Write(value); return; }
            catch { if (delay > 3600) throw; }
            System.Threading.Thread.Sleep(1000*delay);
        }
    }
}

class Program {
    static void Main(string[] args) {
        Console.SetOut(new MyWriter(Console.Out));
        Console.SetError(new MyWriter(Console.Error));
        // etc...
    }
}

答案 1 :(得分:1)

老实说,我认为抽象出Console.WriteLine正是你想要做的。它允许您构建异常处理和重试策略,或允许您的应用程序继续处理文件再次可用时应该执行的任何操作。它也有助于UnitTesting和抽象等等。

然而,说了这么多。您可以在执行任务期间写入本地文件,然后将文件移动到网络共享。这意味着你应该能够“信任”Console.WriteLine将停止工作,这应该避免包装每个调用。然后在任务结束时,您可以将文件移动到网络位置。您可以将这个移动逻辑包装在一大堆错误处理和重试逻辑中,这些逻辑不会影响您现有的代码。