【问题标题】:Will this HTTP Web API call cause deadlock?这个 HTTP Web API 调用会导致死锁吗?
【发布时间】:2021-11-08 20:59:44
【问题描述】:

我想知道您的反馈以优化代码。这会导致死锁或性能问题吗?这是调用 Web API 方法并使用 .Net 4.7

一些帖子建议在使用 GetAsync 时使用 async 和 await 以避免死锁。是否应该使用 HttpRequestException 处理、TaskCanceledException 和 CancelPendingRequests?

public ItemDTO GetItem(int itemId)
 {
    var result = new ItemDTO();
    try
    {
        var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
        var response = client.GetAsync(String.Format(apiUrl + "store/GetItemDetails/{0}", itemId)).Result;

        if (response.IsSuccessStatusCode)
            result = response.Content.ReadAsAsync<ItemDTO>().Result;
        else
            throw new Exception(response.StatusCode + " - " + response.ReasonPhrase);
    }
    catch (Exception ex)
    {
        Store.ManageException.HandleException(ex);
        throw new GetItemsException(ex.Message);
    }
    return result;
 }

更新: 有时 IIS 服务器会挂起。这是 DebugDiag2 分析 - CrashHangAnalysis 报告。这会导致死锁吗?

Thread ID   Total CPU Time  Entry Point for Thread
2   00:00:00.031    ntdll!RtlReleaseSRWLockExclusive+2200
0   00:00:00.030    w3wp+2e50
1   00:00:00.000    nativerd!DllGetClassObject+24680
3   00:00:00.000    ntdll!RtlReleaseSRWLockExclusive+2200
4   00:00:00.000    w3tp!THREAD_POOL::CreateThreadPool+350

4 Threads (40% of all threads) have this same call stack.
Note: Grouping of identical threads can be disabled in the 'Preferences' tab of the Analysis Options
Thread 2 - System ID 4704
Entry point   ntdll!RtlReleaseSRWLockExclusive+2200
Create time   9/20/2021 1:00:34 PM
Time spent in user mode   0 Days 00:00:00.000
Time spent in kernel mode     0 Days 00:00:00.031


This thread is not fully resolved and may or may not be a problem. Further analysis of these threads may be required.
Thread 3 - System ID 2576
Entry point   ntdll!RtlReleaseSRWLockExclusive+2200
Create time   9/20/2021 1:00:34 PM
Time spent in user mode   0 Days 00:00:00.000
Time spent in kernel mode     0 Days 00:00:00.000


This thread is not fully resolved and may or may not be a problem. Further analysis of these threads may be required.
Thread 8 - System ID 2112
Entry point   ntdll!RtlReleaseSRWLockExclusive+2200
Create time   9/20/2021 1:00:34 PM
Time spent in user mode   0 Days 00:00:00.000
Time spent in kernel mode     0 Days 00:00:00.000


This thread is not fully resolved and may or may not be a problem. Further analysis of these threads may be required.
Thread 9 - System ID 5832
Entry point   ntdll!RtlReleaseSRWLockExclusive+2200
Create time   9/20/2021 1:01:04 PM
Time spent in user mode   0 Days 00:00:00.000
Time spent in kernel mode     0 Days 00:00:00.000


This thread is not fully resolved and may or may not be a problem. Further analysis of these threads may be required.
Instruction Address       Source
[0x7ffadb029444]    ntdll!NtWaitForWorkViaWorkerFactory+14    
[0x7ffadaf9eb4e]    ntdll!RtlReleaseSRWLockExclusive+296e     
[0x7ffada7184d4]    kernel32!BaseThreadInitThunk+14   
[0x7ffadafd1781]    ntdll!RtlUserThreadStart+21   

【问题讨论】:

    标签: asp.net-mvc asp.net-web-api optimization async-await deadlock


    【解决方案1】:

    以下是您在使用上述代码时会遇到的问题:

    • GetAsync 的使用是您遇到的最少问题。 您似乎正在从操作 (store/GetItem/{0}) 中调用 GetItems 操作。它正在成为一个递归调用。但是没有终止条件并且通过Http!为此,您的代码中会出现严重的性能问题和堆栈溢出类型问题。
    • 尽量避免抛出异常。如果可能,毫无例外地处理您的业务逻辑。
    • 当您调用 GetItems 操作时,我没有看到任何 Http 状态代码 500(发生异常)被处理。
    • 使用GetAsync,但使用await而不是.Result

    你能描述一下你打算在这里做什么吗?也许创建一个私有函数并从操作中递归调用它。然后当你得到最终结果时,只需从操作中返回它。

    【讨论】:

    • 谢谢@Rahatur。它不会递归调用。抱歉打错字了。它应该是 GetItem() 并返回单个项目详细信息。还有一些其他方法可以返回项目列表。在这种情况下我应该使用 GetAsync() 吗?
    • 在异步函数上使用.Result 是非常糟糕的一个主要问题。请参阅David Fowler's async guidance post 了解更多信息。 2) 抛出异常不是应该避免的。不扔它们隐藏了问题的根本原因,也隐藏了代码中的实际问题。
    • @nbokmans 这个帖子很有帮助。谢谢。
    • @nbokmans 我不建议使用异常。我的建议是在没有异常的情况下处理业务逻辑。
    • @user1979284 我已经更新了我的答案。但是,从 GetItem 操作中调用 store/GetItem/{0} 对我来说似乎是递归的!或者你有两个同名的动作?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    相关资源
    最近更新 更多