簡體   English   中英

ASP.NET 核心 Web ZDB974238714CA8DE634A7CE1D08 應用程序是否可能出現死鎖或應用程序掛起 state

[英]Is deadlock or application hung state possible for ASP.NET Core Web API application

我有一個 ASP.NET Core 3.1 Web API 應用程序,它有一個后台主機服務,我在其中編寫了以下代碼來模擬應用程序的死鎖:

public class Worker : IHostedService
{
    public Task StartAsync(CancellationToken cancellationToken)
    {
        var a = new object();
        var b = new object();

        lock (a)
        {
            lock (b)
            {
            }
        }

        // other thread
        lock (b)
        {
            lock (a)
            {
            }
        }

        return Task.CompletedTask;
    }
}

該應用程序正在運行,但該應用程序不會死鎖或掛起 state,我仍然可以點擊 web api 端點,結果返回給我。

是否有可能使正在運行的 web 應用程序陷入死鎖或掛起 state,以便 API 中的 NONE 沒有給出任何 200 結果?

謝謝。

不確定 ASP.NET,根據您的代碼示例,您可以嘗試使用線程睡眠/延遲之類的東西,這樣每個線程就不會太快地鎖定資源。

可能是這樣的:

        lock (a)
        {
            Thread.sleep(..duration..)

            lock (b)
            {
            }
        }

        // other thread
        lock (b)
        {
            Thread.sleep(..duration..)

            lock (a)
            {
            }
        }

正如所寫,當前方法永遠不會死鎖。

鎖定對象是該方法的本地對象。 正確的鎖定必須使用 scope 之外的 object 方法。

在接下來的版本中,鎖定對象是 static 到 class,鎖定增加了一個微小的延遲來模擬正在執行的工作。 在這種情況下,應用程序將在方法的第二個入口處死鎖。

public class Worker
{
    private static readonly object _a = new();
    private static readonly object _b = new();
    private const int _delay = 5;

    public Task StartAsync2( int n )
    {
        lock( _a )
        {
            Console.WriteLine( $"{n}: _a1 enter" );
            lock( _b )
            {
                Console.WriteLine( $"{n}: _b1 enter" );
                Thread.Sleep( _delay );
            }
            Console.WriteLine( $"{n}: _b1 exit" );
        }
        Console.WriteLine( $"{n}: _a1 exit" );

        // other thread
        lock( _b )
        {
            Console.WriteLine( $"{n}: _b2 enter" );
            lock( _a )
            {
                Console.WriteLine( $"{n}: _a2 enter" );
                Thread.Sleep( _delay );
            }
            Console.WriteLine( $"{n}: _a2 exit" );
        }
        Console.WriteLine( $"{n}: _b2 exit" );

        return Task.CompletedTask;
    }
}

以下是執行Worker導致死鎖的方法:

var w = new Worker();
var t = new Task[5];

for( int i = 0; i < t.Length; i++ )
{
    int n = i;
    t[i] = Task.Run( () =>
    {
        Console.WriteLine( $"{n} start" );
        w.StartAsync2( n );
        Console.WriteLine( $"{n} end" );

        return Task.CompletedTask;
    } );
}

Task.WaitAll( t );

暫無
暫無

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

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