C# taskcanceledexception任务已取消
我收到一个错误 taskcanceledexception在没有任何内部异常详细信息的情况下取消了任务,并且我在Sentry中未收到taskcanceledexception。如何查看此异常的堆栈跟踪是什么,或者需要对代码进行哪些更改 谢谢C# taskcanceledexception任务已取消,c#,exception,logging,httpclient,sentry,C#,Exception,Logging,Httpclient,Sentry,我收到一个错误 taskcanceledexception在没有任何内部异常详细信息的情况下取消了任务,并且我在Sentry中未收到taskcanceledexception。如何查看此异常的堆栈跟踪是什么,或者需要对代码进行哪些更改 谢谢 private T CallDiffbotAndDeserialise<T>(string baseUrl, string pageUrl, int maxTags, int minimumTagConfidencePercentage)
private T CallDiffbotAndDeserialise<T>(string baseUrl, string pageUrl, int maxTags, int minimumTagConfidencePercentage)
{
var client = diffBotConnection.GetClient();
client.BaseAddress = new Uri(baseUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage response = client.GetAsync($"?token={settings.DiffBotToken}&maxTags={maxTags}&tagConfidence={minimumTagConfidencePercentage / 100}&url={Uri.EscapeDataString(pageUrl)}&ts={DateTime.Now.ToSafeCacheString()}").Result;
string responseString = response.Content.ReadAsStringAsync().Result;
T diffBotResponse = JsonConvert.DeserializeObject<T>(responseString);
return diffBotResponse;
}
catch (AggregateException e) // If the task is cancelled or times out
{
return default(T);
};
}
您正在调用
.Result
,它总是抛出aggregateeexception
这意味着您不仅要捕获TaskCancelledException
或OperationCancelledException
,还将捕获对.Result
的两个调用引发的任何内容
因为您正在处理异常并隐藏它曾经发生过的事实(副捕获和返回),所以哨兵不会知道它。如果要将该事件发送给Sentry,则需要手动调用Sentry客户端
与:
使用(仍为预览版):
在本例中,我添加了一个在发生事件时(例如,像上面那样显式捕获异常)与事件一起发送的
还要注意,新的SDK会自动检测未经处理的异常。您的示例不是这样的,因为您正在显式地捕获它
我认为重要的是要提到,理想情况下,您可以通过调用.Result
来避免阻塞线程,而是使用async/await
wait
关键字从出现故障的任务
中打开异常
。
这意味着您的
catch
块现在可以捕获operationCanceledException
。任何其他错误,如连接到服务器的完全失败,都不会进入catch块,反而会在堆栈中冒泡。异常抛出在哪里,因为您知道它被抛出,所以您应该能够找出它来自哪里?顺便说一句,如果任务被取消或超时,捕获一个聚合异常
将捕获比//多得多的内容。旁注:为什么要使用.Result
而不是正确的异步/等待?
public abstract class APIConnection : IDisposable
{
protected HttpClient Client;
private bool disposed = false;
protected APIConnection() : this(3000) { }
protected APIConnection(int timeOut)
{
Client = new HttpClient()
{
Timeout = TimeSpan.FromMilliseconds(timeOut)
};
}
public HttpClient GetClient() => Client;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
Client.Dispose();
}
disposed = true;
}
}
var ravenClient = new RavenClient("dsn"); // Initialize the client
ravenClient.CaptureEvent(new SentryEvent(exception));
// Initialize the SDK only once, at the start of the app
using (SentrySdk.Init("dsn"))
{
SentrySdk.AddBreadcrumb($"Starting a web request to: {baseUrl}");
try
{
// make request
}
catch (Exception e)
{
SentrySdk.CaptureException(exception);
}
}