php小編子墨為您介紹如何在錯誤時停止從通道讀取。在進行通道讀取操作時,有時會遇到錯誤情況,例如通道已關閉或讀取逾時。為了確保程式的穩定性和可靠性,我們需要在這些錯誤發生時及時停止讀取操作。可以透過設定錯誤處理程序或使用異常處理機制來實現,在捕獲到錯誤後,立即終止讀取操作,並進行相應的錯誤處理。這樣可以有效避免程式因錯誤而導致的異常情況,提高程式碼的健全性和可維護性。
一旦遇到錯誤,我想停止從通道讀取。我認為我需要使用 errroup.WithContext() 但我無法完全理解如何整合它。
這是輸出:
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()
# 可能是最好的方法(如你所猜測的)。 這個答案值得一讀;它提供了全面的解釋(我不會嘗試複製!)。
但是,由於這可能很難理解,這裡是使用您的程式碼的一種解決方案(playground ):
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) } }
以上是如何在錯誤時停止從通道讀取?的詳細內容。更多資訊請關注PHP中文網其他相關文章!