【问题标题】:Windows Service Exception When File.Copy()File.Copy() 时的 Windows 服务异常
【发布时间】:2012-06-14 10:17:13
【问题描述】:

我的服务代码位于OnStart() 抛出异常(I)并且服务停止。我不知道为什么会有前任。抛出?..这是我的代码:

public Service1()
{
    InitializeComponent();
}

Thread thread;

protected override void OnStart(string[] args)
{
    thread = new Thread(delegate()
    {
        string path = @"D:\levani\FolderListenerTest\ListenedFolder";
        FileSystemWatcher listener;
        listener = new FileSystemWatcher(path);
        listener.Created += new FileSystemEventHandler(listener_Created);
        listener.EnableRaisingEvents = true;
    });
    thread.Start();
}

public void listener_Created(object sender, FileSystemEventArgs e)
{
    File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\F" + e.Name);
}

protected override void OnStop()
{
    thread.Abort();
}

日志

Log Name:      Application
Source:        .NET Runtime
Date:          6/11/2012 5:33:27 PM
Event ID:      1026
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      Levan-PC
Description:
Application: FolderListenerService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
Stack:
   at System.IO.__Error.WinIOError(Int32, System.String)
   at System.IO.File.InternalCopy(System.String, System.String, Boolean)
   at System.IO.File.Copy(System.String, System.String)
   at FolderListenerService.Service1.listener_Created(System.Object, System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32, System.String)
   at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name=".NET Runtime" />
    <EventID Qualifiers="0">1026</EventID>
    <Level>2</Level>
    <Task>0</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2012-06-11T14:33:27.000000000Z" />
    <EventRecordID>18314</EventRecordID>
    <Channel>Application</Channel>
    <Computer>Levan-PC</Computer>
    <Security />
  </System>
  <EventData>
    <Data>Application: FolderListenerService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
Stack:
   at System.IO.__Error.WinIOError(Int32, System.String)
   at System.IO.File.InternalCopy(System.String, System.String, Boolean)
   at System.IO.File.Copy(System.String, System.String)
   at FolderListenerService.Service1.listener_Created(System.Object, System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32, System.String)
   at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
</Data>
  </EventData>
</Event>

【问题讨论】:

  • 您有 0 个错误处理。您还没有准备好编写 Windows 服务。 FileSystemWatcher 的 Created 事件几乎总是在文件仍在使用时被触发。在涉足服务之前,您需要掌握控制台应用程序中的代码!
  • 我已经从我的工作控制台应用程序中重写了代码;)

标签: c# file exception windows-services io


【解决方案1】:

这可能是多种原因。请参阅 File.Copy() 文档,尤其是 Exceptions 部分,该部分记录了所有可能引发的异常。

您需要包装您的 File.Copy() 并捕获任何异常,以便做出适当的反应:

public void listener_Created(object sender, FileSystemEventArgs e)
{
    try
    {
        File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\F" + e.Name);
    }
    catch {FileNotFoundException e)
    { 
        //do something if file isn't there
    }
    catch {UnauthorizedAccessException e)
    { 
        //do something if invalid permissions
    }

    //etc 
}

【讨论】:

    【解决方案2】:

    File.Copy 中的额外参数 true 将覆盖已存在的文件。我认为错误是文件已经存在。

    File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\F" + e.Name,true);
    

    将代码放入try..catch block 并捕获IOException 异常。您可以登录文件进行进一步调试。

    当文件名、目录名或卷标语法不正确时,我们会收到WinIOError 错误(当我们进入调用堆栈时)。所以只需检查正确的路径和文件名。

    【讨论】:

    • 你认为这是问题所在?
    【解决方案3】:

    我不知道为什么,但是在我用 try {} catch {} 包围我的代码之后,它运行良好,有什么想法吗?这是代码:

    public Service1()
            {
                InitializeComponent();
            }
    
            Thread thread;
    
            protected override void OnStart(string[] args)
            {
                try
                {
                    thread = new Thread(delegate()
                    {
                        string path = @"D:\levani\FolderListenerTest\ListenedFolder";
                        FileSystemWatcher listener; listener = new FileSystemWatcher(path);
                        listener.Created += new FileSystemEventHandler(listener_Created);
                        listener.EnableRaisingEvents = true;
                    });
                    thread.Start();
                }
                catch (Exception ex)
                {
                    File.WriteAllText(@"D:\levani\bussite.txt", "thread: " + ex.ToString());
                }
            }
    
            public void listener_Created(object sender, FileSystemEventArgs e)
            {
                try
                {
                    File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\F" + e.Name);
                }
                catch (Exception ex)
                {
                    File.WriteAllText(@"D:\levani\bussite.txt", "File copy ex: " + ex.ToString());
                }
            }
    
            protected override void OnStop()
            {
                thread.Abort();
            }
    

    【讨论】:

    • 那么 bussite.txt 包含什么?您正在记录异常,因此请阅读它。
    • 有写入的文件被另一个进程使用。我得到了这个,但我如何让那个文件没有被使用?该文件已完全上传?
    • 这是因为您现在正在单独的线程中捕获listener_Created 引发的异常。如我的回答所述,在 Thread.Start() 创建的线程中抛出的任何未处理的异常都会导致您的应用程序终止。
    【解决方案4】:

    如果您创建一个新线程,您需要确保处理该线程上抛出的所有异常。 在由 Thread.Start() 创建的线程上发生的任何未处理的异常都会导致您的应用程序终止。

    具体来说,构造函数FileSystemWatcher(string path)File.Copy(string sourceFileName, string destFileName) 会抛出一些您在当前代码中未处理的异常。这两个都在一个单独的线程上调用。由于文件已经存在,您很可能会收到 IOException(对同一个文件进行多次更改会导致您的代码尝试多次复制它,从而导致第一次之后的任何副本发生冲突)。

    您可能应该更新您的 File.Copy 调用以使用 File.Copy(string sourceFileName, string destFileName, bool overwrite) 并将您的 listener_Created 函数包装在一个 try/catch 块中,该块会处理异常(而不是重新抛出它)。

    【讨论】:

    • 是的,它因异常而停止,我在日志中看到了,但文件夹存在,更重要的是,它在我复制我的服务代码的控制台应用程序中工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2011-08-27
    • 2014-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多