มีอะไรใหม่ใน .NET Core 2 และ C# 7 : App ไม่ค้างตอนอ่านไฟล์ใหญ่

App ไม่ค้างตอนอ่านไฟล์ใหญ่
ซี่งปรกติ App จะค้างเหมือนหยุดการทำงานไปจนกว่าจะอ่านไฟล์เสร็จ
ซึ่งอาจทำให้ผู้ใช้คิดว่า App มีปัญหาในการทำงาน
หากเรานำเทคนิคการใช้คำสั่ง async และ wait จะช่วยให้ App ไม่ค้าง
ผู้ใช้ยังคงมีปฏิสัมพันธ์กับ App ต่อไปได้
เราจะลองเขียนโค้ดภาษา C# กับ .NET Core 2.0 เพื่อทดสอบการทำงานของคำสั่ง async และ await
โดย 2 คำสั่งนี้ช่วยให้เกิดการทำงานคู่ขนาน
วิธีใช้คำสั่ง async ทำได้โดยนำไปใส่ไว้หน้าส่วนนิยามMethodที่ต้องการ
Method ที่ว่านี้มีข้อจำกัดที่จะมีค่าส่งกลับได้ 3 แบบ คือ void, Task และ Task<TResult> เท่านั้น
ดังนั้นโดยทั่วไปแล้วเรามักใช้ async Method ที่เป็น Method บริการอีเวนต์ เช่น
- Method ที่ตอบสนองการกดปุ่ม
- Method รับข้อมูลจาก พอร์ทสื่อสาร และ
- Method ตอบสนอง timer
เนื่องจาก void ไม่ได้ส่งอะไรกลับ ทำให้เมื่อเราเรียก Method แล้วก็ไม่ต้องรอรับอะไร สามารถทำงานบรรทัดคำสั่งถัดไปได้เลย ไม่ต้องรอให้มันทำงานเสร็จก่อน
ค่าส่งกลับแบบ Task อันที่จริงไม่ได้ส่งค่าอะไรกลับมา เราจึงไม่ต้อง และ ไม่สามารถรอรับสิ่งที่มันจะส่งกลับมาได้
ส่วน Method ที่มีค่าส่งกลับแบบ Task<TResult> เราสามารถกำหนดสิ่งที่จะส่งกลับได้
ยกตัวอย่างเช่น ถ้าเราต้องการส่งกลับค่าบูลีน เพื่อเป็นเครื่องแสดงความสำเร็จหรือล้มเหลว เราจะเขียนว่า Task<bool>
ในโค้ดตัวอย่างแสดงวิธีใช้คำสั่ง async
เราสร้างโปรเจ็กต์แบบ Win Form แล้วใส่ปุ่ม Label และ Timer ให้ทำงานทุก ๆ 1 วินาที
ทุกครั้งที่ Timer รอครบ 1 วินาที method asyncTimer_Tick จะทำงานเพื่อแสดงจำนวนวินาทีในการทำงาน
เมื่อผู้ใช้กดปุ่มจะเกิดการคัดลอกไฟล์ขนาดใหญ่หลายไฟล์
บรรทัดที่ 19-24 กำหนดต้นทางและปลายทางของไฟล์ reset เริ่มการทำงานของ Timer แล้วสร้างรายชื่อของไฟล์ที่จะคัดลอก
บรรทัด 29-47 เริ่มกระบวนการคัดลอกไฟล์จากต้นทางไปปลายทาง
บรรทัด 38 คือคำสั่งที่ทำให้เกิดการคัดลอก ตัวเลข 81920 คือขนาด buffer
โปรดสังเกตว่าบรรทัดนี้มีตัวกระทำ await นำหน้า เพื่อให้เกิดการทำงานที่จะไม่ทำให้ Thread อื่น ๆ ค้าง
ระหว่างที่มันกำลังคัดลอกไฟล์ ผู้ใช้ยังคงสามารถโยกย้ายยืดหดหน้าฟอร์มได้และ Label ยังแสดงข้อความได้
การทำ Serialization กับ type ของเราเอง
การทำ Serialization หรือที่เรียกอีกอย่างหนึ่งว่าการทำ marshalling
คือ การแปลงภาวะของ object ให้กลายเป็น byte ข้อมูลในรูปแบบต่าง ๆ เช่น binary , XML และ JSON
เพื่อเก็บเป็น stream ไว้ในสื่อบันทึกหรือเพื่อส่งไปยังระบบอื่น ๆ ภายในเครือข่าย type ต่าง ๆ ของภาษา และ. Net มีคุณสมบัตินี้
และเราสามารถเขียนโค้ด C# กับ .NET Core เพื่อให้ typeของเราเองมีคุณสมบัตินี้ได้ด้วยเช่นกัน
Type ที่เรานิยามเองอาจเป็น class generic class , Enum และ Struct
ยกตัวอย่างเหตุการณ์ที่เราอาจจำเป็นต้องใช้ Serialization คือ
เราทำงานหนึ่งอยู่และต้องการพักงานนั้นไว้ชั่วคราว
โดยต้องการเก็บสถานะหรือภาวะของobjectทั้งหมดไว้ในฮาร์ดดิสก์
เพื่อที่จะสามารถนำกลับมาทำงานต่อภายหลัง ได้อย่างต่อเนื่องจากที่ทำค้างไว้
บรรทัดที่ 4 นำเข้า Name Space System.Runtime.Serialization.Formatters.Binary
เพราะต้องการใช้เมธอด Serialize ในคลาส BinaryFormatter ของ Name Space นี้
บรรทัด 9-14 นิยามคลาส Cat ซึ่งในนั้นมีแค่ฟิลด์ Weight และ Age
โปรดสังเกตว่าคลาสนี้เป็น Abstract Class และ เราต้องการทำให้คลาสนี้มีความสามารถทำ Serialization ได้
เราจึงจำเป็นจะต้องใส่แอตทริบิวต์ชื่อ [Serializable] ไว้ที่บรรทัดก่อนหน้านิยามคลาส
และเราต้องการทำให้คลาสนี้มีความสามารถทำ Serialization ด้วยเช่นกัน
จึงต้องใส่แอตทริบิวต์ [Serializable] ไว้ก่อนหน้านิยามคลาส
ทั้งนี้เพราะความ Serialization จะไม่สืบสันดานจากเบสคลาสไปยังคลาสอนุพันธ์
คลาสอนุพันธ์จะต้องกำหนด Serialization ของมันเอง
โปรดสังเกตว่า Method นี้มีค่าส่งกลับเป็น Stream ซึ่งเป็นตัวเก็บข้อมูลสถานะของ Object ที่ถูกทำ Serialization แล้ว
มันสร้าง Object จากคลาส Tiger แล้วกำหนดคุณสมบัติต่าง ๆ คือ Age, IsTamed, Trainer และ Weight ให้แก่ Object
จากนั้นบรรทัด 30 ใช้ Method BinaryFormatter() เพื่อแปลง Object tiger ให้กลายเป็น Serialization และอยู่ในรูปแบบสตรีมแล้วส่งกลับไปให้โค้ดที่เรียกมัน
โดยใช้โค้ดอย่างที่เห็นใน Method DeserializeTiger()
Method นี้รับพารามิเตอร์หนึ่งตัวเป็น Serialization ที่อยู่ในรูปแบบ stream
เราสามารถกำหนดตำแหน่งใน stream ที่จะเริ่มแปลงข้อมูลกลับได้โดยกำหนดที่พรอพเพอร์ตี Position ของ stream
กระบวนการแปลงเกิดขึ้นที่บรรทัด 39 โดยการเรียกMethod Deserializa() ของคลาส BinaryFormatter
บรรทัด 45-47 คือโค้ดที่ใช้เพื่อทดสอบการทำงานของคลาสนี้
อย่างไร ทดลองเขียนใช้คำสั่ง async และ wait ด้วยภาษา C# กับ .NET Core 2.0
เพื่อช่วยให้ App ไม่ค้าง ส่งผลดีทำให้ผู้ใช้ยังคงมีปฏิสัมพันธ์กับ App ต่อไปได้ดูนะครับ