สมมติว่าฉันมีคลาสกว่า 100 คลาสที่ใช้อินเทอร์เฟซทั่วไปด้วยวิธี "คำนวณ" คลาสบางคลาสจะดำเนินการแบบอะซิงก์ (เช่น อ่านไฟล์) และคลาสอื่น ๆ ที่ใช้อินเทอร์เฟซเดียวกันจะรันโค้ดที่ซิงค์ (เช่น การเพิ่มตัวเลขสองตัว) วิธีที่ดีในการเขียนโค้ดนี้ เพื่อการบำรุงรักษาและเพื่อประสิทธิภาพคืออะไร
โพสต์ที่ฉันอ่านจนถึงตอนนี้ แนะนำให้สร้างเมธอด async/await ให้กับผู้โทรเสมอ ดังนั้น หากคุณมีการดำเนินการหนึ่งที่เป็นอะซิงก์ ให้ทำให้ผู้เรียกเป็นอะซิงก์ จากนั้นจึงทำให้ผู้เรียกเป็นอะซิงก์ และอื่นๆ นี่ทำให้ฉันคิดว่าอินเทอร์เฟซควรเป็นอินเทอร์เฟซแบบอะซิงก์ อย่างไรก็ตาม สิ่งนี้จะสร้างปัญหาเมื่อใช้อินเทอร์เฟซกับโค้ดที่เป็นแบบซิงโครนัส
แนวคิดหนึ่งที่ฉันคิดคือการเปิดเผยในอินเทอร์เฟซ 2 วิธี หนึ่งอะซิงก์และการซิงค์หนึ่งรายการ และคุณสมบัติบูลีนหนึ่งรายการเพื่อบอกผู้โทรว่าจะโทรหาวิธีใด แม้ว่านี่จะดูน่าเกลียดจริงๆก็ตาม
รหัสที่ฉันมีในปัจจุบันเป็นเพียงวิธีอินเทอร์เฟซเดียวที่ไม่ตรงกัน จากนั้นสำหรับการใช้งานแบบซิงโครนัส จะมีการล้อมโค้ดไว้ภายในวัตถุงาน:
using System.IO;
using System.Threading.Tasks;
namespace TestApp
{
interface IBlackBox
{
Task<string> PullText();
}
sealed class MyAsyncBlackBox : IBlackBox
{
public async Task<string> PullText()
{
using (var reader = File.OpenText("Words.txt"))
{
return await reader.ReadToEndAsync();
}
}
}
sealed class MyCachedBlackBox : IBlackBox
{
public Task<string> PullText()
{
return Task.Run(() => "hello world");
}
}
}
นี่เป็นแนวทางที่ถูกต้องในการสร้างและใช้งานอินเทอร์เฟซที่บางครั้งก็ไม่ตรงกันหรือไม่? ฉันมีคลาสจำนวนมากที่ใช้การดำเนินการซิงโครนัสระยะสั้น และกังวลว่าการดำเนินการนี้อาจเพิ่มค่าใช้จ่ายจำนวนมาก มีวิธีอื่นในการทำเช่นนี้ที่ฉันขาดหายไปหรือไม่?
Task.Run(...)
ให้ใช้Task.FromResult(...);
ไลบรารีของคุณไม่ควรใช้Task.Run(...)
เพราะนั่นจะใช้เธรดใหม่ (ค่อนข้างซับซ้อนกว่านั้น) แทนที่จะทำงานบนเธรดที่ดำเนินการอยู่ในปัจจุบัน - person Nelson   schedule 01.04.2019