簡體   English   中英

taskcanceledexception一個任務被取消

[英]taskcanceledexception a task was canceled

我收到錯誤taskcanceledexception,一個任務被取消,沒有任何內部異常詳細信息,並且我在Sentry中未收到取消任務的異常。 我如何查看此異常的堆棧跟蹤是什么,或者需要對代碼進行哪些更改?

謝謝

    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);
        };
    }

API連接:

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;
        }
    }

您正在調用.Result ,它總是拋出AggregateException

這意味着您不僅要捕獲TaskCancelledExceptionOperationCancelledException ,而且還要捕獲兩次對.Result調用所引發的任何事情。

由於您正在處理異常並隱藏了發生過的事實(通過捕獲和返回),Sentry不會知道它。 如果要將事件發送到Sentry,則需要手動調用Sentry客戶端。

使用SharpRaven

var ravenClient = new RavenClient("dsn"); // Initialize the client
ravenClient.CaptureEvent(new SentryEvent(exception));

使用新的SDK,Sentry正在開發 (仍是預覽版):

// 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);
    }
}

在此示例中,我添加了一個面包屑 ,如果發生事件(例如,捕獲上述類似的異常),該面包屑將與事件一起發送。

還要注意,新的SDK會自動檢測未處理的異常。 舉例來說,情況並非如此,因為您明確地抓住了它。

我認為重要的是要提到,理想情況下,您應避免通過調用.Result阻塞線程 ,而應使用async/await

await關鍵字從出現故障的Task解開Exception 這意味着您的catch塊現在可以捕獲OperationCancelledException 其他任何錯誤(例如完全無法連接到服務器)都不會進入您的catch塊,而會使堆棧冒泡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM