某些NGit内容会阻止C#应用程序正确关闭
我正在尝试在我的应用程序(C#,MS.NET 4.0)中使用。由于我们在MS平台上,我已经在VS2010下为.NET Framework 4.0重建了NGit。大多数情况都很好,所有功能都运行良好,但应用程序仍处于关闭状态。VS Debugger显示,来自锐化库的一些线程无限地处于等待状态,并且没有人向它发出关闭信号。当我使用某些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
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)
):
我确实得到了图书馆并进行了测试。我发现一些相关测试间歇性失败。我不知道测试用例是否错误,或者是否存在实际问题 我在这里报告了这个问题: 我将看一看您添加的特定代码,我刚刚看到了它
我在上测试了以下代码
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");
}
}
}