赶上退出代码3

时间:2015-08-04 09:38:59

标签: c# winforms

我有一个简单的永无止境的winforms背景应用程序,可以将网络摄像头中的图片保存在硬盘上,有些可以使用它们,然后删除它们。图片保存和处理是两个独立的过程,第一个更快一点。为了不使带有图片的磁盘过载,我设置了一个可以保存的图片计数限制。为此,我使用字符串队列。

问题是有时app会因退出代码3(ERROR_PATH_NOT_FOUND)而崩溃。从我的代码中发现这似乎是不可能的,因为我只使用了一条路径而且它没有受到任何影响。我也在try catch块中设置了所有可能的东西,但没有抓到任何东西。我认为它可能来自我使用的两个更大的库中的一个。有没有办法找到这个令人讨厌的事情发生的地方?

好的,这是保存图像的代码:

void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs) 
{
    videoSource.NewFrame -= videoSource_NewFrame;
    if (snapshotsQueue.Count < 100) 
    {
        Image myImage = (Image)eventArgs.Frame.Clone();
        string strGrabFileName;
        if (firstFrame) 
        {
            firstFrame = false;
            // extension is png
            strGrabFileName = String.Format(
                "{0}\\{1}.{2}", snapshotsPath, "0.0", 
                snapshotExtension.ToString().ToLowerInvariant()); 
            snapshotTimer.Start();
        }
        else 
        {
            strGrabFileName = String.Format(
                "{0}\\{1}.{2}", snapshotsPath,
                snapshotTimer.Elapsed.TotalSeconds.ToString(CultureInfo.InvariantCulture), snapshotExtension.ToString().ToLowerInvariant());
        }

        try 
        {
            myImage.Save(strGrabFileName, snapshotExtension);
            snapshotsQueue.Enqueue(strGrabFileName);
        } 
        catch (Exception e) 
        {
            writeError(e.Message);
            writeToLog(e.Message);
        }
    }

    Thread.Sleep(100);
    if (videoSource != null) 
    {
        videoSource.NewFrame += videoSource_NewFrame;
    }
}

文件阅读:

while (true) 
{
    try 
    {
        if (videoSource == null && snapshotsQueue.Count == 0) return;
        while (snapshotsQueue.Count == 0) Thread.Sleep(100);
        var snapshot = snapshotsQueue.Dequeue();

        // process image
        File.Delete(snapshot);    
    } 
    catch (Exception ex) 
    {
        writeError(ex.Message);
    }
}

2 个答案:

答案 0 :(得分:1)

您可以抓住ThreadException和所有UnhandledException s:

static void Main()
{
    Application.ThreadException += new ThreadExceptionEventHandler(HandleThreadException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(HandleUnhandledException);

    //... do your stuff
}

static void HandleThreadException(object sender, ThreadExceptionEventArgs e)
{
   //log the exception or something else
}

static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
   //log the exception or something else
}

这应该能够捕捉到其他地方未被捕获的所有例外情况! UnhandledExceptionEventHandler捕获主UI线程中的异常,而ThreadExceptionEventHandler会收到非UI线程中未捕获异常的通知。

如需进一步阅读,请参阅UnhandledException EventThreadException Event上的MSDN。您甚至可能必须设置UnhandledExceptionMode

答案 1 :(得分:0)

我真的不建议这是一个长期的答案 - 但你可以做一个整体应用程序捕获甚至重新启动你的应用程序。

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.OnThreadException += MyHandler;
AppDomain.CurrentDomain.UnhandledException += otherHandler;

你可以将它放在应用程序的program.cs中

我建议您考虑将其转换为服务而不是经常运行的应用程序..我也无法帮助,但感觉有错误陷阱,您可以在应用程序的某个地方更优雅地做。

在您的处理程序中,您当然可以使用那个半终端

Application.Restart();

听起来完全一样。