Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk berhenti membaca dari saluran atas kesilapan?
Editor PHP Zimo akan memperkenalkan anda cara berhenti membaca daripada saluran apabila ralat berlaku. Semasa menjalankan operasi bacaan saluran, anda kadangkala menghadapi keadaan ralat, seperti saluran ditutup atau tamat masa bacaan. Untuk memastikan kestabilan dan kebolehpercayaan program, kami perlu menghentikan operasi baca dalam masa apabila ralat ini berlaku. Ini boleh dicapai dengan menyediakan pengendali ralat atau menggunakan mekanisme pengendalian pengecualian Selepas menangkap ralat, operasi baca akan ditamatkan serta-merta dan pengendalian ralat yang sepadan akan dilakukan. Ini dengan berkesan boleh mengelakkan situasi tidak normal yang disebabkan oleh ralat dalam program dan meningkatkan keteguhan dan kebolehselenggaraan kod.
Saya mahu berhenti membaca dari saluran apabila ralat ditemui. Saya rasa saya perlu menggunakan errroup.WithContext() tetapi saya tidak begitu memahami cara mengintegrasikannya.
Ini adalah output:
Thread 2: STARTED Thread 1: STARTED Thread 0: STARTED Thread 2: GOT=0 Thread 1: GOT=1 Thread 0: GOT=2 Thread 0: FAILED Thread 1: GOT=3 Thread 2: GOT=4 Thread 2: GOT=5 Thread 1: GOT=6 Thread 1: GOT=7 Thread 2: GOT=8 panic: Thread 0: FAILED
package main import ( "fmt" "time" "golang.org/x/sync/errgroup" ) func main() { const threads = 3 ch := make(chan int, threads) eg := errgroup.Group{} for i := 0; i < threads; i++ { i := i eg.Go(func() error { fmt.Printf("Thread %d: STARTED\n", i) for n := range ch { fmt.Printf("Thread %d: GOT=%d\n", i, n) time.Sleep(time.Duration(1) * time.Second) // Simulate failed thread if n == 2 { fmt.Printf("Thread %d: FAILED\n", i) return fmt.Errorf("Thread %d: FAILED", i) } } return nil }) } for i := 0; i < 9; i++ { ch <- i } close(ch) if err := eg.Wait(); err != nil { panic(err) } }
................................................. ............... ................................... ..
errroup.WithContext()
Mungkin cara terbaik (seperti yang anda sangka). Jawapan ini patut dibaca; ia memberikan penjelasan yang komprehensif (yang saya tidak akan cuba salin!).
Namun, memandangkan ini mungkin sukar difahami, berikut ialah penyelesaian menggunakan kod anda (taman permainan ):
package main import ( "context" "fmt" "time" "golang.org/x/sync/errgroup" ) func main() { const threads = 3 ch := make(chan int, threads) eg, ctx := errgroup.WithContext(context.Background()) for i := 0; i < threads; i++ { i := i eg.Go(func() error { fmt.Printf("Thread %d: STARTED\n", i) for n := range ch { fmt.Printf("Thread %d: GOT=%d\n", i, n) time.Sleep(time.Duration(1) * time.Second) // Simulate failed thread if n == 2 { fmt.Printf("Thread %d: FAILED\n", i) return fmt.Errorf("Thread %d: FAILED", i) } // For the purpose of this example we will just check the context after // doing the work. if ctx.Err() != nil { fmt.Printf("Thread %d: Quiting due to context\n", i) return fmt.Errorf("Thread %d: Context cancelled: ", i) } } return nil }) } // We want to stop sending new work if there is a failure (otherwise `ch <- i` will block permanently); sendLoop: for i := 0; i < 9; i++ { select { case ch <- i: case <-ctx.Done(): fmt.Printf("stopped\n") break sendLoop // Just exit the loop if something goes wrong (you may want to do something else here) } } close(ch) // Note: Important that this happens even if there is an error (otherwise `for n := range ch` may block, leaking goroutines) fmt.Printf("all sent\n") if err := eg.Wait(); err != nil { panic(err) } }
Atas ialah kandungan terperinci Bagaimana untuk berhenti membaca dari saluran atas kesilapan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!