第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Async-await:線程會一直運行到我的等待嗎?

Async-await:線程會一直運行到我的等待嗎?

C#
翻翻過去那場雪 2021-11-07 20:17:36
我一直認為如果我調(diào)用一個異步函數(shù),線程就會開始執(zhí)行這個異步函數(shù),直到它看到一個等待。我認為它會向上調(diào)用堆棧查看調(diào)用者是否沒有等待,而不是無所事事地等待。如果沒有,則執(zhí)行代碼??紤]以下(簡化的)代碼:async Task<string> FetchCustomerNameAsync(int customerId){    // check if customerId is positive:    if (customerId <= 0) throw new ArgumentOutofRangeException(nameof(customerId);    // fetch the Customer and return the name:    Customer customer = await FetchCustomerAsync(customerId);    return customer.Name;}現(xiàn)在,如果我的異步函數(shù)FetchCustomerNameAsync(+1)不等待就調(diào)用會發(fā)生什么:var myTask = FetchCustmerNameAsync(+1);DoSomethingElse();string customerName = await myTask;FetchCustomerNameAsync, 以 +1 的參數(shù)值調(diào)用FetchCustomerNameAsync檢測到它customerId是陽性的,所以也不例外FetchCustomerNameAsync 電話 FetchCustomerAsync里面的某個地方FetchCustomerAsync是一個等待。發(fā)生這種情況時,線程會向上調(diào)用調(diào)用堆棧,直到其中一個調(diào)用者沒有等待。FetchCustomerNameAsync 正在等待,所以調(diào)用堆棧我的功能還沒有等待,繼續(xù) DoSomethingElse()我的功能滿足等待。我的想法是,在滿足我函數(shù)中的 await 之前,已經(jīng)完成了對參數(shù)值的檢查。因此,以下應在 await 之前導致異常:// call with invalid parameter; do not awaitvar myTask = FetchCustmerNameAsync(-1);      // <-- note the minus 1!Debug.Assert(false, "Exception expected");我認為雖然我沒有等待,但在Debug.Assert.然而,在我的程序中,在 Debug.Assert為什么之前沒有拋出異常?到底發(fā)生了什么?
查看完整描述

3 回答

?
繁星淼淼

TA貢獻1775條經(jīng)驗 獲得超11個贊

異常僅在等待任務(wù)時傳播

您不能在不等待任務(wù)的情況下處理異常。異常僅在線程/任務(wù)內(nèi)傳播。因此,如果您不等待,異常只會停止任務(wù)。如果在您等待之前拋出異常,它將在您實際等待時傳播。


之前做所有的驗證,然后做異步工作。

所以,我建議你之前驗證:


ValidateId(id); // This will throw synchronously.

Task<Customer> customer = FetchCustomerAsync(id).ConfigureAwait(false);

DoSomethingElse();

return await customer.Name;

這是實現(xiàn)您想要的并行性的最佳方式。


查看完整回答
反對 回復 2021-11-07
?
慕萊塢森

TA貢獻1810條經(jīng)驗 獲得超4個贊

您是對的,該線程執(zhí)行異步函數(shù)直到它看到等待。事實上,你ArgumentOutofRangeException是由你調(diào)用的線程拋出的FetchCustmerNameAsync。即使它是同一個線程也不會得到異常的原因是因為當您await在函數(shù)內(nèi)部使用時,AsyncStateMachine構(gòu)建了 a 。它將所有代碼轉(zhuǎn)換為狀態(tài)機,但重要的部分是它如何處理異常??匆豢矗?/p>


這段代碼:


public void M() {


    var t = DoWork(1);


}


public async Task DoWork(int amount)

{

    if(amount == 1)

        throw new ArgumentException();


    await Task.Delay(1);

}

轉(zhuǎn)換為(我跳過了不重要的部分):


private void MoveNext()

{

    int num = <>1__state;

    try

    {

        TaskAwaiter awaiter;

        if (num != 0)

        {

            if (amount == 1)

            {

                throw new ArgumentException();

            }

            awaiter = Task.Delay(1).GetAwaiter();

            if (!awaiter.IsCompleted)

            {

                // Unimportant

            }

        }

        else

        {

            // Unimportant

        }

    }

    catch (Exception exception)

    {

        <>1__state = -2;

        <>t__builder.SetException(exception); // Add exception to the task.

        return;

    }

    <>1__state = -2;

    <>t__builder.SetResult();

}

如果你跟著<>t__builder.SetException(exception);( AsyncMethodBuilder.SetException),你會發(fā)現(xiàn)它最終會調(diào)用task.TrySetException(exception);which 將異常添加到任務(wù)的 中exceptionHolder,可以通過Task.Exception屬性檢索。


查看完整回答
反對 回復 2021-11-07
?
catspeake

TA貢獻1111條經(jīng)驗 獲得超0個贊

一個簡化的 MCVE :


    static async Task Main(string[] args)

    {       

        try

        {

          // enable 1 of these calls

            var task = DoSomethingAsync();

          //  var task = DoSomethingTask();


            Console.WriteLine("Still Ok");

            await task;

        }

        catch (Exception ex)

        {

            Console.WriteLine(ex.Message);                

        }

    }


    private static async Task DoSomethingAsync()

    {

        throw new NotImplementedException();            

    }


    private static Task DoSomethingTask()

    {

        throw new NotImplementedException();

        return Task.CompletedTask;

    }

當您調(diào)用 DoSomethingAsync 時,您將看到“Still Ok”消息。


當您調(diào)用 DoSomethingTask 時,您將獲得您期望的行為:WriteLine 之前的立即異常。


查看完整回答
反對 回復 2021-11-07
  • 3 回答
  • 0 關(guān)注
  • 432 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號