WithCancel i WithTimeout
Tworzenie kontekstów możliwych do anulowania i ograniczonych czasowo
WithCancel i WithTimeout to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.
context.WithCancel
WithCancel wyprowadza nowy kontekst wraz z funkcją anulowania. Wywołanie cancel zamyka kanał Done wyprowadzonego kontekstu i wszystkich jego kontekstów podrzędnych.
ctx, cancel := context.WithCancel(parent)
defer cancel() // always call to release resources
go doWork(ctx)Zawsze używaj defer cancel
Nie wywołując cancel, powodujesz wyciek gorutyny monitorującej kontekst nadrzędny. Zawsze używaj defer cancel natychmiast po utworzeniu kontekstu, który można anulować.
context.WithTimeout
WithTimeout wyprowadza kontekst, który automatycznie anuluje się po upływie określonego czasu. Jest to wygodna nakładka na WithDeadline.
ctx, cancel := context.WithTimeout(parent, 5*time.Second)
defer cancel()
if err := db.QueryContext(ctx, query); err != nil {
// err may be context.DeadlineExceeded
}Sprawdzanie Err()
Po zamknięciu Done funkcja ctx.Err() zwraca przyczynę: context.Canceled (jawne anulowanie) albo context.DeadlineExceeded (przekroczenie limitu czasu).
if err := ctx.Err(); errors.Is(err, context.DeadlineExceeded) {
log.Println("timeout")
}Anulowanie z innej gorutyny
Funkcję cancel można bezpiecznie wywołać z dowolnej gorutyny, a także równocześnie z wielu gorutyn. Skutek ma tylko pierwsze wywołanie.
ctx, cancel := context.WithCancel(context.Background())
go func() {
if detectError() { cancel() }
}()Limit czasu żądania HTTP
Ustaw limit czasu dla pojedynczego żądania za pomocą WithTimeout na kontekście odebranego żądania:
func handler(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()
result, err := service.Call(ctx)
// ...
}Kaskadowe anulowanie
Jeśli kontekst nadrzędny zostanie anulowany, wszystkie wyprowadzone konteksty (podrzędne i wnuki) zostaną automatycznie anulowane, zatrzymując wszystkie gorutyny w drzewie wywołań.
Context w testach
Używaj context.Background() lub context.WithTimeout w testach, aby ograniczyć czas działania gorutyn uruchamianych przez testy.
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
testResult := runTest(ctx)Propagowanie context przez biblioteki
Zawsze przekazuj otrzymany context do wywołań wychodzących (zapytań do baz danych, wywołań HTTP i RPC). Nie odrzucaj go ani nie zastępuj, chyba że masz konkretny powód, aby zresetować termin.
Tworzenie context dla zadania w tle
W przypadku zadań w tle, które nie są powiązane z żądaniem, użyj context.Background() jako kontekstu głównego i dodaj WithCancel, aby można było poprawnie zatrzymać zadanie.
select z Done
Zawsze używaj select z ctx.Done() równolegle z kanałem pracy, aby uniknąć blokowania, gdy kontekst zostanie anulowany przed zakończeniem pracy.
select {
case result := <-workCh:
return result, nil
case <-ctx.Done():
return nil, ctx.Err()
}Szybki test
Jaka jest różnica między context.WithCancel a context.WithTimeout?
Podsumowanie: WithCancel i WithTimeout
Najważniejsze informacje:
- Zawsze używaj defer cancel() natychmiast po utworzeniu kontekstu
- WithTimeout anuluje kontekst automatycznie po upływie określonego czasu; zwraca DeadlineExceeded
- ctx.Err() rozróżnia Canceled i DeadlineExceeded
- Anulowanie jest propagowane do wszystkich wyprowadzonych kontekstów
Często zadawane pytania
Czy lekcja „WithCancel i WithTimeout” jest bezpłatna?
Tak — pełny tekst „WithCancel i WithTimeout” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „WithCancel i WithTimeout”?
Tworzenie kontekstów możliwych do anulowania i ograniczonych czasowo Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Go Academy?
Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „WithCancel i WithTimeout”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?
Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dlaczego istnieje context.Context
- WithCancel i WithTimeout
- WithDeadline i WithValue
- Kontekst w wywołaniach HTTP i baz danych