12/04/2026 18:17น.

EP.62 การใช้ Context ใน Golang เพื่อจัดการกับการทำงานที่มีการรอคอย (concurrent tasks)
#การทำงานพร้อมกันใน Golang
#การตั้งเวลาใน Golang
#การยกเลิกงานใน Golang
#การจัดการ concurrent tasks ใน Golang
#Concurrent tasks Golang
#Golang context
แพ็กเกจ Context ใน Golang เป็นเครื่องมือที่สำคัญเมื่อเราทำงานกับ concurrent tasks มันช่วยให้เราสามารถจัดการ task ที่รอคอย, จัดการการยกเลิก, และตั้งเวลาให้กับการทำงานที่อาจใช้เวลานาน ในตอนนี้เราจะเรียนรู้วิธีการใช้ context เพื่อควบคุมการทำงานหลายๆ งานพร้อมกันและให้สามารถยกเลิกหรือตั้งเวลาให้กับการทำงานเหล่านั้นได้อย่างมีประสิทธิภาพ การใช้ context จะช่วยให้เราจัดการกับทรัพยากรได้อย่างเหมาะสม และช่วยในการสร้างแอปพลิเคชันที่มีประสิทธิภาพและสามารถขยายตัวได้
ทำไม Context ถึงสำคัญ?
แพ็กเกจ Context ใช้สำหรับการจัดการการทำงานที่มีการรอคอยหลายๆ งานพร้อมกัน โดยสามารถ:
- ยกเลิกงานที่ไม่จำเป็น: เราสามารถยกเลิก task ได้เมื่อไม่ต้องการให้มันทำงาน เช่น เมื่อผู้ใช้ยกเลิกคำขอหรือเมื่อเซิร์ฟเวอร์ปิด
- ตั้งเวลา: เราสามารถตั้งเวลาให้กับงานที่ทำงานนานเกินไป โดยไม่ให้มันทำงานต่อไปได้
- ส่งข้อมูลข้าม goroutine:
contextช่วยให้เราสามารถส่งข้อมูล (เช่น กำหนดเวลา หรือสัญญาณยกเลิก) ไปยัง goroutine ต่างๆ ได้อย่างสะดวก
ข้อดีของการใช้ Context:
- การจัดการทรัพยากรที่ดีขึ้น: ช่วยให้เราควบคุมทรัพยากรได้ดีขึ้น และมั่นใจว่าไม่มีการทำงานที่ไม่จำเป็นต่อไป
- การจัดการ concurrency ได้ง่ายขึ้น: ช่วยให้เราแยกการจัดการงานที่ทำงานพร้อมกันให้ชัดเจนและง่ายต่อการดูแล
- การยกเลิกและตั้งเวลา: สามารถยกเลิกหรือตั้งเวลาให้กับงานต่างๆ ได้อย่างมีประสิทธิภาพ ช่วยให้การทำงานไม่ถูกบล็อกหรือล่าช้า
โครงสร้างการทำงานของ Context
แพ็กเกจ context ใน Golang ออกแบบมาเพื่อส่งสัญญาณการยกเลิก, กำหนดเวลา, หรือส่งข้อมูลข้าม goroutine ระหว่างการทำงานหลายๆ งาน
ส่วนประกอบหลักของ Context:
- Context Objects:
context.Background()– ใช้เป็น context รากฐานcontext.TODO()– ใช้เมื่อไม่แน่ใจว่าจะใช้ context อะไรcontext.WithCancel()– สร้าง context ที่สามารถยกเลิกได้context.WithTimeout()– สร้าง context ที่มีการตั้งเวลาcontext.WithDeadline()– สร้าง context ที่มีการตั้งกำหนดเวลา
- การยกเลิก:
- เราสามารถยกเลิก context โดยใช้
cancel()และการยกเลิกนี้จะส่งผลให้ goroutines ที่ใช้ context นั้นได้รับสัญญาณยกเลิก
- เราสามารถยกเลิก context โดยใช้
- การตั้งเวลาและกำหนดเวลา:
- สามารถตั้งเวลาให้กับงานเพื่อป้องกันไม่ให้มันทำงานนานเกินไป
วิธีการใช้ Context ในการจัดการกับ Concurrent Tasks
การใช้ context กับหลายๆ concurrent tasks ต้องส่ง context ไปยังทุกๆ goroutine เพื่อให้แต่ละ goroutine สามารถรับสัญญาณการยกเลิกหรือการตั้งเวลา
ขั้นตอนการใช้งาน:
- สร้าง Context:
ใช้context.Background()หรือcontext.TODO()เป็น context รากฐาน - รัน Concurrent Tasks:
เมื่อสร้าง goroutines ให้ส่ง context ไปให้เพื่อให้แต่ละงานสามารถตรวจสอบการยกเลิกและการตั้งเวลาได้ - การยกเลิก:
ใช้context.WithCancel()เพื่อสร้าง context ที่สามารถยกเลิกได้ และเมื่อยกเลิก context งานที่เชื่อมโยงกับ context นี้จะได้รับสัญญาณยกเลิก - การตั้งเวลา:
ใช้context.WithTimeout()เพื่อตั้งเวลาให้กับการทำงาน ซึ่งจะยกเลิกการทำงานหากงานนั้นใช้เวลานานเกินไป
ตัวอย่างโค้ดสำหรับการจัดการ Concurrent Tasks ด้วย Context
การใช้
contextในการยกเลิก Concurrent Tasks
package main
import (
"context"
"fmt"
"time"
)
func task(ctx context.Context, id int) {
select {
case <-time.After(2 * time.Second): // จำลองงานที่ใช้เวลา
fmt.Printf("Task %d completed\n", id)
case <-ctx.Done(): // ถ้า context ถูกยกเลิก
fmt.Printf("Task %d canceled\n", id)
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
for i := 1; i <= 5; i++ {
go task(ctx, i)
}
time.Sleep(4 * time.Second) // รอให้งานเสร็จหรือล้มเหลว
}
ในโค้ดนี้ เราสร้าง context ที่มีเวลา 3 วินาที และถ้างานใช้เวลานานเกินไปมันจะถูกยกเลิก
การใช้ Context กับการยกเลิกสำหรับงานที่ทำงานนาน
package main
import (
"context"
"fmt"
"time"
)
func longRunningTask(ctx context.Context) {
for {
select {
case <-time.After(1 * time.Second):
fmt.Println("Running task...")
case <-ctx.Done(): // ตรวจจับการยกเลิก
fmt.Println("Task canceled")
return
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go longRunningTask(ctx)
time.Sleep(3 * time.Second)
cancel() // ยกเลิกงานหลังจาก 3 วินาที
}
ในตัวอย่างนี้ เราใช้ context.WithCancel() เพื่อยกเลิกงานที่ทำงานนานเกินไป
การทดสอบ Concurrent Tasks ด้วย Context
หลังจากที่เราใช้ context แล้ว การทดสอบระบบจะช่วยให้มั่นใจว่า tasks ถูกจัดการได้อย่างมีประสิทธิภาพ
การทดสอบที่ควรทำ:
- ทดสอบการยกเลิกงาน: ตรวจสอบว่างานสามารถยกเลิกได้เมื่อ context ถูกยกเลิก
- ทดสอบการตั้งเวลา: ตรวจสอบว่างานที่เกินเวลาจะถูกยกเลิก
- ทดสอบการซิงโครไนซ์ของ goroutines: ตรวจสอบว่า goroutines ทำงานร่วมกันได้และทำงานตามที่ต้องการเมื่อได้รับสัญญาณยกเลิก
ท้าให้ลอง!
ลองนำ context ในการจัดการคำขอ HTTP มาจัดการเวลาและยกเลิกคำขอที่ใช้เวลานาน!
EP ถัดไป:
ใน EP ถัดไป เราจะมาดู การสร้างระบบการยืนยันตัวตนผู้ใช้ (User Authentication System) สำหรับ WebSocket เพื่อให้ผู้ใช้สามารถยืนยันตัวตนก่อนเข้าร่วมห้องแชท!