ใช้งบและรอคำหลักเล่นอย่างดีใน c #


102

ฉันมีสถานการณ์ที่ฉันasyncโทรไปยังเมธอดที่ส่งคืนและIDisposableอินสแตนซ์ ตัวอย่างเช่น:

HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com"));

ก่อนหน้าasyncนี้อยู่ในที่เกิดเหตุเมื่อทำงานกับIDisposableอินสแตนซ์การโทรและรหัสที่ใช้ตัวแปร "response" นี้จะรวมอยู่ในคำสั่งใช้

คำถามของฉันคือยังคงเป็นแนวทางที่ถูกต้องหรือไม่เมื่อasyncคีย์เวิร์ดถูกโยนเข้าไปในส่วนผสม? แม้ว่าโค้ดจะคอมไพล์ แต่คำสั่งใช้จะยังคงทำงานตามที่คาดไว้ในทั้งสองตัวอย่างด้านล่างนี้หรือไม่

ตัวอย่าง 1

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    // Do something with the response

    return true;
}

ตัวอย่าง 2

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    await this.responseLogger.LogResponseAsync(response);

    return true;
}

คำตอบ:


98

ใช่ว่าจะดี

ในกรณีแรกคุณกำลังพูดว่า:

  • แบบอะซิงโครนัสรอจนกว่าเราจะได้รับคำตอบ
  • ใช้มันและกำจัดมันทันที

ในกรณีที่สองคุณกำลังพูดว่า:

  • แบบอะซิงโครนัสรอจนกว่าเราจะได้รับคำตอบ
  • รอจนกว่าเราจะบันทึกการตอบกลับแบบอะซิงโครนัส
  • ทิ้งการตอบกลับ

usingคำสั่งในวิธี async เป็น "แปลก" ในที่Disposeโทรอาจดำเนินการในหัวข้อที่แตกต่างกันไปอีกทางหนึ่งซึ่งกลายเป็นทรัพยากร (ขึ้นอยู่กับบริบทการประสาน ฯลฯ ) แต่จะยังคงเกิดขึ้น ... สมมติว่าสิ่งที่คุณกำลังรอสำหรับเคยปรากฏหรือล้มเหลวแน่นอน (เช่นเดียวกับคุณจะไม่จบลงด้วยการเรียกDisposeใช้รหัสที่ไม่ใช่ async หากusingคำสั่งของคุณมีการเรียกใช้วิธีการที่ไม่มีวันกลับมา)


4
ขอบคุณจอน ในขณะที่สิ่งที่ async ส่วนใหญ่ยังคงเป็นวูดูสำหรับฉัน แต่ก็ค่อนข้างมั่นใจว่ามันรวมเข้ากับคุณสมบัติ. net อื่น ๆ บ่อยแค่ไหนและใช้งานได้จริง
swingdoctor

@JonSkeet ควรรอแม้กระทั่งการใช้งานภายในusing(){...}บล็อกหรือเป็นการใช้งานมากเกินไปหรืออาจลดประสิทธิภาพในบางกรณี? ไม่using(){...}ตอบสนองวัตถุประสงค์เช่นเดียวกับawait?
น.

1
@nam: ไม่usingและawaitตอบสนองวัตถุประสงค์ที่แตกต่างกันอย่างสิ้นเชิง โปรดทราบว่าขณะนี้ C # 8 มีการกำจัดแบบอะซิงโครนัสเช่นกัน ในขณะที่มันคุ้มค่าของการตระหนักถึงปัญหาเกลียวคำตอบของฉันไฮไลท์ที่แน่นอนไม่ได้หมายความว่ามันเป็นเรื่องที่ไม่ถูกต้องในการผสมและusing await
Jon Skeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.