国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

異步編程異常和死鎖處理

2019-11-14 14:10:51
字體:
來源:轉載
供稿:網友

 

在.NET異步編程中,通常使用async和await這對黃金搭檔,返回類型使用Task或Task<T>。在方法前面加async表示這個方法運行異步,在方法內使用await表示執行一個異步等待。

 

下面是一個簡單例子:

 

        static void Main(string[] args)
        {
            Doth();
            Console.ReadKey();
        }
        static async Task Doth()
        {
            int i = 2;
            await Task.Delay(TimeSpan.FromSeconds(2));
            i += 2;
            await Task.Delay(TimeSpan.FromSeconds(2));
            Console.WriteLine(i);
        }

 

當執行DoSth方法,第一個await執行一個異步等待,當執行完成,就繼續執行下面的代碼。在async修飾的方法內部,一個await就是一個異步等待,可以包含多個await, 每一個await執行完畢才會執行它后面的代碼,也就是說在DoSth內部是同步的。

 

各個await在哪個線程中運行呢?

 

默認情況下是在當前線程中運行,不過.NET提供了ConfigureAwait方法,用來設置await在哪個線程中運行。

 

        static async Task Doth()
        {
            int i = 2;
            await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
            i += 2;
            await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
            Console.WriteLine(i);
        }

 

以上,當第一個await運行在控制臺項目所在的線程中,第二個await將在線程池上運行。

 

我們無法保證每個await不會拋出異常,通常按如下的方式捕獲異常。

 

async Task DosthAsync()
{
    try
    {
        await PossibleExceptionAsync();
    }
    catch(NotSuppotedException ex)
    {
        LogException(ex);
        throw;
    }
}

 

由于拋出的異常會放在Task對象中,所以也可以這么寫:

 

async Task DosthAsync()
{
    Task task = PossibleExceptionAsync();
    try
    {
        await task;
    }
    cach(NotSupportedException ex)
    {
        LogException(ex);
        throw;
    }
}

 

異步編程也會出現死鎖。

 

async Task DoSthSync()
{
    await Task.Delay(TimeSpan.FromSeconds(1));
}
void FirstThing()
{
    Task tak = DoSthSync();
    task.Wait();
}

 

以上,如果調用FirstThing方法就會出現死鎖的情況。

 

→執行FirstThing方法
→在FirstThing方法內部執行DoSthSync方法,這時,當前上下文線程被阻塞
→來到DoSthSync方法中,其中的await試圖捕獲當前上下文線程,而當前的上下線程已經被阻塞在那里了,造成死鎖。

 

死鎖如何解決死鎖呢?

 

可以在DoSthSync內部不使用當前上下文線程,改用線程池中的線程,修改如下:

 

async Task DoSthSync()
{
    await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
}

 

或者,讓FirstThing變成一個異步方法。修改如下:

 

async Task DoSthSync()
{
    await Task.Delay(TimeSpan.FromSeconds(1));
}
async Task FirstThing()
{
    await DoSthSync();
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南通市| 师宗县| 濮阳县| 黎平县| 乌鲁木齐市| 云安县| 新乡县| 华亭县| 阿图什市| 宁津县| 永新县| 溧水县| 临猗县| 全椒县| 中牟县| 宁武县| 兖州市| 凭祥市| 堆龙德庆县| 孝昌县| 准格尔旗| 旬邑县| 汉沽区| 冕宁县| 香格里拉县| 北碚区| 文山县| 宁陵县| 阿拉尔市| 陆河县| 平阴县| 长春市| 个旧市| 富阳市| 洛南县| 建始县| 怀集县| 儋州市| 沅江市| 扶沟县| 唐山市|