一些NGit会阻止C#应用程序正确关闭

时间:2011-06-10 18:41:18

标签: c# .net multithreading git

我正在尝试在我的应用程序中使用NGit library(C#,MS.NET 4.0)。由于我们在MS平台上,我已经在VS 2010下重建了.NET Framework 4.0的NGit。大多数事情都很好,所有功能都运行良好,但应用程序在关闭时挂起。 VS Debugger显示来自Sharpen lib的某些线程无限期地处于等待状态,并且没有人将其发送到关闭状态。当我使用NGit.Api.Git类的任何实例方法时,会发生这种情况(对于静态方法,似乎没问题)。有没有人遇到过这样的问题?有什么建议吗?

使用Git类的代码示例:

Git myrepo = Git.Init().SetDirectory(@"C:\myrepo.git").SetBare(true).Call();
FetchResult fetchResult = myrepo.Fetch()
    .SetProgressMonitor(new TextProgressMonitor())
    .SetRemote(@"C:\projects\initialrepo")
    .SetRefSpecs(new RefSpec("refs/heads/master:refs/heads/master"))
    .Call();
//
// Some other work...
//
myrepo.GetRepository().Close();

以下是线程挂起的地方:

班级Sharpen.ThreadExecutor,第9行(St.Monitor.Wait (pendingTasks)):

public void RunPoolThread ()
{
    while (!IsTerminated ()) {
        try {
            Runnable r = null;
            lock (pendingTasks) {
                freeThreads++;
                while (!IsTerminated () && pendingTasks.Count == 0)
                    ST.Monitor.Wait (pendingTasks);
                if (IsTerminated ())
                    break;
                r = pendingTasks.Dequeue ();
            }
            if (r != null)
                r.Run ();
        }
        catch (ST.ThreadAbortException) {
            ST.Thread.ResetAbort ();
        }
        catch {
        }
    }
}

1 个答案:

答案 0 :(得分:3)

我确实得到了库并运行了测试。我发现一些相关的测试间歇性地失败了。我不知道测试用例是否错误或是否存在实际问题。

我在这里报告了这个问题:https://github.com/slluis/ngit/issues/8

我会看看你添加的特定代码,我刚看到它


我在

上测试了以下代码
  1. Linux(Mono 2.6.7,.NET 3.5)
  2. Linux(Mono 2.11,.NET 4.0)
  3. 问题似乎是静态BatchingProgressMonitor(当你没有注册TextProgressMonitor也是构建的)永远不会“被破坏”,这意味着alarmQueue与它相关联的线程池永远不会Shutdown

    如果您将以下公共方法添加到课程BatchingProgressMonitor

    public static void ShutdownNow()
    {
        alarmQueue.ShutdownNow();
    }
    

    在退出应用程序之前,您可以通过调用BatchingProgressMonitor.ShutdownNow()来获得“解决方法”。这 WorkedForMe TM 。示例代码显示了删除#if/#endif

    时如何执行此操作

    using System;
    using NGit;
    using NGit.Api;
    using NGit.Transport;
    
    namespace Stacko
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                Git myrepo = Git.Init().SetDirectory(@"/tmp/myrepo.git").SetBare(true).Call();
                {
                    var fetchResult = myrepo.Fetch()
                        .SetProgressMonitor(new TextProgressMonitor())
                        .SetRemote(@"/tmp/initial")
                        .SetRefSpecs(new RefSpec("refs/heads/master:refs/heads/master"))
                        .Call();
                    //
                    // Some other work...
                    //
                    myrepo.GetRepository().Close();
                }
                System.GC.Collect();
    
    #if false
                System.Console.WriteLine("Killing");
                BatchingProgressMonitor.ShutdownNow();
    #endif
                System.Console.WriteLine("Done");
    
            }
        }
    }
    

    我也会在问题跟踪器上报告这个问题。 修改完成:here

    干杯, 塞特