为构建轮询 Microsoft.VisualStudio.Services.Client 时出现 NullReferenceException
NullReferenceException when polling Microsoft.VisualStudio.Services.Client for builds
我正在尝试实现一个简单的轮询服务,该服务查询我们的 TFS 实例以获取构建结果(最终这将显示在办公室的构建监视器上)。根据示例 here,我进行了以下尝试:
var uri = new Uri("http://tfs:8080/tfs/defaultcollection");
var connection = new VssConnection(uri, new VssClientCredentials());
var client = connection.GetClient<BuildHttpClient>();
var builds = await client.GetBuildsAsync(
project: "OurProject",
maxBuildsPerDefinition: 1,
type: DefinitionType.Build);
但最后一条语句在客户端库的某个深处抛出 NullReferenceException
(底部的完整堆栈跟踪)。
我已经尝试了以下方法,它确实有效,但当然它没有为我提供我正在寻找的信息:)
var client = connection.GetClient<WorkItemTrackingHttpClient>();
var workItems = await client.GetWorkItemsAsync(ids: new List<int> { 7000, 7005});
我是不是对如何查询构建有根本性的误解?如何避免此异常?
更新:不仅仅是我!
我刚刚发现这个错误不是(仅)在客户端产生的;它也在服务器端!对以下 url 的 GET
请求:
http://tfs:8080/tfs/defaultCollection/OurProject/_apis/build/builds?api-version=2.0&maxBuildsPerDefinition=1&type=build
产生一个 500 Internal Server Error
响应,内容如下:
{
"$id": "1",
"innerException": null,
"message": "Object reference not set to an instance of an object.",
"typeName": "System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"typeKey": "NullReferenceException",
"errorCode": 0,
"eventId": 0
}
遇到这种情况,我该如何排查?我应该 ask/tell 作为 运行 我们 TFS 服务器的运维人员做什么?我们在寻找什么?
(客户端)异常的堆栈跟踪:
Unhandled Exception: System.AggregateException: One or more errors occurred.
---> Microsoft.VisualStudio.Services.WebApi.VssServiceResponseException: Object reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
--- End of inner exception stack trace ---
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.HandleResponse(HttpResponseMessage response)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__49.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__47`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__53`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__52`1.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at ConsoleApplication1.Program.Work() in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 32
at ConsoleApplication1.Program.Main(String[] args) in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 20
我发现了错误。简短回答,RTFM :)
事实证明,maxBuildsPerDefinition
参数只有在同时指定了definitions
的情况下才有效。如果只给前者,服务器returns500.
(你可能会争辩说 401 Bad Request 会是更好的回应,但至少现在我知道该怎么做了。)
我的解决方法是改为在客户端进行过滤;我得到所有项目的所有构建,然后按定义和 select 最新的分组:
var builds = await client
.GetBuildsAsync(
project: "OurProject",
type: DefinitionType.Build).Result
.GroupBy(build => build.Definition.Id)
.Select(g => g
.OrderByDescending(build.FinishTime ?? build.StartTime ?? DateTime.MinValue)
.First());
我正在尝试实现一个简单的轮询服务,该服务查询我们的 TFS 实例以获取构建结果(最终这将显示在办公室的构建监视器上)。根据示例 here,我进行了以下尝试:
var uri = new Uri("http://tfs:8080/tfs/defaultcollection");
var connection = new VssConnection(uri, new VssClientCredentials());
var client = connection.GetClient<BuildHttpClient>();
var builds = await client.GetBuildsAsync(
project: "OurProject",
maxBuildsPerDefinition: 1,
type: DefinitionType.Build);
但最后一条语句在客户端库的某个深处抛出 NullReferenceException
(底部的完整堆栈跟踪)。
我已经尝试了以下方法,它确实有效,但当然它没有为我提供我正在寻找的信息:)
var client = connection.GetClient<WorkItemTrackingHttpClient>();
var workItems = await client.GetWorkItemsAsync(ids: new List<int> { 7000, 7005});
我是不是对如何查询构建有根本性的误解?如何避免此异常?
更新:不仅仅是我!
我刚刚发现这个错误不是(仅)在客户端产生的;它也在服务器端!对以下 url 的 GET
请求:
http://tfs:8080/tfs/defaultCollection/OurProject/_apis/build/builds?api-version=2.0&maxBuildsPerDefinition=1&type=build
产生一个 500 Internal Server Error
响应,内容如下:
{
"$id": "1",
"innerException": null,
"message": "Object reference not set to an instance of an object.",
"typeName": "System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"typeKey": "NullReferenceException",
"errorCode": 0,
"eventId": 0
}
遇到这种情况,我该如何排查?我应该 ask/tell 作为 运行 我们 TFS 服务器的运维人员做什么?我们在寻找什么?
(客户端)异常的堆栈跟踪:
Unhandled Exception: System.AggregateException: One or more errors occurred.
---> Microsoft.VisualStudio.Services.WebApi.VssServiceResponseException: Object reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
--- End of inner exception stack trace ---
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.HandleResponse(HttpResponseMessage response)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__49.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__47`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__53`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__52`1.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at ConsoleApplication1.Program.Work() in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 32
at ConsoleApplication1.Program.Main(String[] args) in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 20
我发现了错误。简短回答,RTFM :)
事实证明,maxBuildsPerDefinition
参数只有在同时指定了definitions
的情况下才有效。如果只给前者,服务器returns500.
(你可能会争辩说 401 Bad Request 会是更好的回应,但至少现在我知道该怎么做了。)
我的解决方法是改为在客户端进行过滤;我得到所有项目的所有构建,然后按定义和 select 最新的分组:
var builds = await client
.GetBuildsAsync(
project: "OurProject",
type: DefinitionType.Build).Result
.GroupBy(build => build.Definition.Id)
.Select(g => g
.OrderByDescending(build.FinishTime ?? build.StartTime ?? DateTime.MinValue)
.First());