某些NGit内容会阻止C#应用程序正确关闭

某些NGit内容会阻止C#应用程序正确关闭,c#,.net,multithreading,git,C#,.net,Multithreading,Git,我正在尝试在我的应用程序(C#,MS.NET 4.0)中使用。由于我们在MS平台上,我已经在VS2010下为.NET Framework 4.0重建了NGit。大多数情况都很好,所有功能都运行良好,但应用程序仍处于关闭状态。VS Debugger显示,来自锐化库的一些线程无限地处于等待状态,并且没有人向它发出关闭信号。当我使用NGit.Api.Git类的任何实例方法时,就会发生这种情况(对于静态方法,情况似乎还可以)。有人经历过这样的问题吗?有什么建议吗 使用Gitclass的代码示例: Git

我正在尝试在我的应用程序(C#,MS.NET 4.0)中使用。由于我们在MS平台上,我已经在VS2010下为.NET Framework 4.0重建了NGit。大多数情况都很好,所有功能都运行良好,但应用程序仍处于关闭状态。VS Debugger显示,来自锐化库的一些线程无限地处于等待状态,并且没有人向它发出关闭信号。当我使用
NGit.Api.Git
类的任何实例方法时,就会发生这种情况(对于静态方法,情况似乎还可以)。有人经历过这样的问题吗?有什么建议吗

使用
Git
class的代码示例:

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();
这是挂线的地方:

Class
锐化.ThreadExecutor
,第9行(
St.Monitor.Wait(pendingTasks)
):


我确实得到了图书馆并进行了测试。我发现一些相关测试间歇性失败。我不知道测试用例是否错误,或者是否存在实际问题

我在这里报告了这个问题:

我将看一看您添加的特定代码,我刚刚看到了它


我在上测试了以下代码

  • Linux(Mono 2.6.7、.NET3.5)
  • Linux(Mono 2.11、.NET 4.0)
  • 问题似乎是静态
    BatchingProgressMonitor
    (在未注册
    TextProgressMonitor
    时也会构造)从未被“破坏”,这意味着与其关联的线程池的alarmQueue从未被
    关闭

    如果将以下公共方法添加到类
    BatchingProgressMonitor

    public static void ShutdownNow()
    {
        alarmQueue.ShutdownNow();
    }
    
    在退出应用程序之前,您可以通过调用批处理进程监视器.ShutdownNow()
    找到“解决方法”。这对我很有效。示例代码显示了在删除
    #if/#endif
    时如何执行此操作

    我也会在问题追踪器上报告编辑完成:

    干杯,
    Seth

    也许会发布一个简单的例子来演示这个问题?听起来你应该对如何使用NGit库做更多的研究。如果有帮助的话,我已经添加了代码示例。
    @Ramhound
    我有。谢谢你的宝贵意见。这应该挂起,它甚至可以证明流产。了解如何脉冲pendingTasks锁并获取IsTerminated()以返回true。应该有某种公共方法可以做到这一点。谢谢
    @sehe
    !我期待着你的回应。@Dmitry Zorin:我想我找到了原因,并提供了无力的解决办法。这其实不需要,我也不建议您将其用于任何严肃的工作,但它仍然表明,调用Shutdownow将解决挂起的问题
    @sehe:
    非常感谢。你证实了我对错误来源的怀疑,也证实了没有公开的东西可以处理它。是的,您的解决方案在我的环境(Windows 7 x64,MS.NET Framework 4.0)上运行良好,但您是对的,这只是一个解决方案。这应该在库级别以某种方式处理。感谢您报告这些问题,非常感谢您的参与,这真的很有帮助。
    据我所知,这些问题已经解决。您不需要再显式地关闭线程了。如果您可以用最新翻译的代码重现挂起/死锁,请重新打开此问题。
    -真酷!再次感谢@sehe的参与,非常有帮助!
    public static void ShutdownNow()
    {
        alarmQueue.ShutdownNow();
    }
    
    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");
    
            }
        }
    }