Udostępnij za pośrednictwem


Wyzwalacz czasomierza dla usługi Azure Functions

W tym artykule wyjaśniono, jak pracować z wyzwalaczami czasomierza w usłudze Azure Functions. Wyzwalacz czasomierza umożliwia uruchamianie funkcji zgodnie z harmonogramem.

Są to informacje referencyjne dla deweloperów usługi Azure Functions. Jeśli dopiero zaczynasz korzystać z usługi Azure Functions, zacznij od następujących zasobów:

Aby uzyskać informacje na temat ręcznego uruchamiania funkcji wyzwalanej przez czasomierz, zobacz Ręczne uruchamianie funkcji niezwolonej przez protokół HTTP.

Obsługa tego powiązania jest automatycznie udostępniana we wszystkich środowiskach deweloperskich. Nie musisz ręcznie instalować pakietu ani rejestrować rozszerzenia.

Kod źródłowy pakietu rozszerzenia czasomierza znajduje się w repozytorium GitHub azure-webjobs-sdk-extensions .

Ważne

W tym artykule są używane karty do obsługi wielu wersji modelu programowania Node.js. Model w wersji 4 jest ogólnie dostępny i ma bardziej elastyczne i intuicyjne środowisko dla deweloperów języka JavaScript i Języka TypeScript. Aby uzyskać więcej informacji na temat sposobu działania modelu w wersji 4, zapoznaj się z przewodnikiem dewelopera dotyczącym usługi Azure Functions Node.js. Aby dowiedzieć się więcej o różnicach między wersjami 3 i v4, zapoznaj się z przewodnikiem migracji.

Usługa Azure Functions obsługuje dwa modele programowania dla języka Python. Sposób definiowania powiązań zależy od wybranego modelu programowania.

Model programowania w języku Python w wersji 2 umożliwia definiowanie powiązań przy użyciu dekoratorów bezpośrednio w kodzie funkcji języka Python. Aby uzyskać więcej informacji, zobacz przewodnik dla deweloperów języka Python.

Ten artykuł obsługuje oba modele programowania.

Przykład

W tym przykładzie pokazano funkcję języka C#, która jest wykonywana za każdym razem, gdy minuty mają wartość podzielną na pięć. Na przykład gdy funkcja rozpoczyna się o godzinie 18:55:00, następne wykonanie wynosi 19:00:00. Obiekt TimerInfo jest przekazywany do funkcji.

Funkcję języka C# można utworzyć przy użyciu jednego z następujących trybów języka C#:

  • Model izolowanego procesu roboczego: skompilowana funkcja języka C#, która jest uruchamiana w procesie roboczym izolowanym od środowiska uruchomieniowego. Proces izolowanego procesu roboczego jest wymagany do obsługi funkcji języka C# uruchomionych w wersjach LTS i innych niż LTS platformy .NET oraz programu .NET Framework. Rozszerzenia dla izolowanych funkcji procesu roboczego używają Microsoft.Azure.Functions.Worker.Extensions.* przestrzeni nazw.
  • Model przetwarzania: skompilowana funkcja języka C#, która działa w tym samym procesie co środowisko uruchomieniowe usługi Functions. W odmianie tego modelu funkcje można uruchamiać przy użyciu skryptów języka C#, które są obsługiwane głównie w przypadku edytowania portalu języka C#. Rozszerzenia dla funkcji przetwarzania używają Microsoft.Azure.WebJobs.Extensions.* przestrzeni nazw.

Ważne

Wsparcie zostanie zakończone dla modelu procesu 10 listopada 2026 r. Zdecydowanie zalecamy przeprowadzenie migracji aplikacji do izolowanego modelu procesu roboczego w celu uzyskania pełnej obsługi.

//<docsnippet_fixed_delay_retry_example>
[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
    FunctionContext context)
{
    var logger = context.GetLogger(nameof(TimerFunction));

Poniższa przykładowa funkcja wyzwala i wykonuje co pięć minut. Adnotacja @TimerTrigger w funkcji definiuje harmonogram przy użyciu tego samego formatu ciągu co wyrażenia CRON.

@FunctionName("keepAlive")
public void keepAlive(
  @TimerTrigger(name = "keepAliveTrigger", schedule = "0 */5 * * * *") String timerInfo,
      ExecutionContext context
 ) {
     // timeInfo is a JSON string, you can deserialize it to an object using your favorite JSON library
     context.getLogger().info("Timer is triggered: " + timerInfo);
}

W poniższym przykładzie przedstawiono powiązanie wyzwalacza czasomierza i kod funkcji, który używa powiązania, w którym wystąpienie reprezentujące czasomierz jest przekazywane do funkcji. Funkcja zapisuje dziennik wskazujący, czy wywołanie tej funkcji jest spowodowane nieodebranym wystąpieniem harmonogramu. Przykład zależy od tego, czy używasz modelu programowania w wersji 1, czy w wersji 2 języka Python.

import datetime
import logging
import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="mytimer")
@app.timer_trigger(schedule="0 */5 * * * *", 
              arg_name="mytimer",
              run_on_startup=True) 
def test_function(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().replace(
        tzinfo=datetime.timezone.utc).isoformat()
    if mytimer.past_due:
        logging.info('The timer is past due!')
    logging.info('Python timer trigger function ran at %s', utc_timestamp)

W poniższym przykładzie przedstawiono funkcję TypeScript wyzwalacza czasomierza.

import { app, InvocationContext, Timer } from '@azure/functions';

export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<void> {
    context.log('Timer function processed request.');
}

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    handler: timerTrigger1,
});

W poniższym przykładzie przedstawiono funkcję JavaScript wyzwalacza czasomierza.

const { app } = require('@azure/functions');

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    handler: (myTimer, context) => {
        context.log('Timer function processed request.');
    },
});

Oto dane powiązania w pliku function.json :

{
    "schedule": "0 */5 * * * *",
    "name": "myTimer",
    "type": "timerTrigger",
    "direction": "in"
}

Poniżej znajduje się kod funkcji czasomierza w pliku run.ps1:

# Input bindings are passed in via param block.
param($myTimer)

# Get the current universal time in the default string format.
$currentUTCtime = (Get-Date).ToUniversalTime()

# The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
if ($myTimer.IsPastDue) {
    Write-Host "PowerShell timer is running late!"
}

# Write an information log with the current time.
Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"

Atrybuty

Biblioteka języka C# w procesie używa atrybutu TimerTriggerAttribute z pliku Microsoft.Azure.WebJobs.Extensions, natomiast biblioteka języka C# izolowanego procesu roboczego używa atrybutu TimerTriggerAttribute z elementu Microsoft.Azure.Functions.Worker.Extensions.Timer w celu zdefiniowania funkcji. Zamiast tego skrypt języka C# używa pliku konfiguracji function.json.

Właściwość atrybutu opis
Zaplanuj Wyrażenie CRON lub wartość TimeSpan. Element TimeSpan może być używany tylko dla aplikacji funkcji działającej w planie usługi App Service. Możesz umieścić wyrażenie harmonogramu w ustawieniu aplikacji i ustawić tę właściwość na nazwę ustawienia aplikacji opakowaną w % znaki jako %ScheduleAppSetting%.
RunOnStartup Jeśli truefunkcja jest wywoływana po uruchomieniu środowiska uruchomieniowego. Na przykład środowisko uruchomieniowe jest uruchamiane, gdy aplikacja funkcji wznawia się po przejściu w stan bezczynności z powodu braku aktywności. gdy aplikacja funkcji zostanie uruchomiona ponownie z powodu zmian funkcji i gdy aplikacja funkcji zostanie skalowana w poziomie. Należy zachować ostrożność. Polecenie RunOnStartup powinno rzadko być ustawione na truewartość , zwłaszcza w środowisku produkcyjnym.
UseMonitor Ustaw na wartość true lub false, aby wskazać, czy harmonogram powinien być monitorowany. Monitorowanie harmonogramu utrwala wystąpienia harmonogramu, aby pomóc w zapewnieniu prawidłowej konserwacji harmonogramu nawet po ponownym uruchomieniu wystąpień aplikacji funkcji. Jeśli nie ustawiono jawnie, wartością domyślną jest true harmonogramy z interwałem cyklu większym lub równym 1 minucie. W przypadku harmonogramów wyzwalających więcej niż raz na minutę wartość domyślna to false.

Dekoratory

Dotyczy tylko modelu programowania w wersji 2 języka Python.

W przypadku funkcji języka Python w wersji 2 zdefiniowanych przy użyciu dekoratora następujące właściwości w pliku schedule:

Właściwości opis
arg_name Nazwa zmiennej reprezentującej obiekt czasomierza w kodzie funkcji.
schedule Wyrażenie NCRONTAB lub wartość TimeSpan. Element TimeSpan może być używany tylko dla aplikacji funkcji działającej w planie usługi App Service. Możesz umieścić wyrażenie harmonogramu w ustawieniu aplikacji i ustawić tę właściwość na nazwę ustawienia aplikacji opakowaną w % znaki, jak w tym przykładzie: "%ScheduleAppSetting%".
run_on_startup Jeśli truefunkcja jest wywoływana po uruchomieniu środowiska uruchomieniowego. Na przykład środowisko uruchomieniowe jest uruchamiane, gdy aplikacja funkcji wznawia się po przejściu w stan bezczynności z powodu braku aktywności. gdy aplikacja funkcji zostanie uruchomiona ponownie z powodu zmian funkcji i gdy aplikacja funkcji zostanie skalowana w poziomie. Należy zachować ostrożność. parametr runOnStartup powinien rzadko być ustawiony na truewartość , szczególnie w środowisku produkcyjnym.
use_monitor Ustaw na wartość true lub false, aby wskazać, czy harmonogram powinien być monitorowany. Monitorowanie harmonogramu utrwala wystąpienia harmonogramu, aby pomóc w zapewnieniu prawidłowej konserwacji harmonogramu nawet po ponownym uruchomieniu wystąpień aplikacji funkcji. Jeśli nie ustawiono jawnie, wartością domyślną jest true harmonogramy z interwałem cyklu większym lub równym 1 minucie. W przypadku harmonogramów wyzwalających więcej niż raz na minutę wartość domyślna to false.

Aby zapoznać się z funkcjami języka Python zdefiniowanymi przy użyciu function.json, zobacz sekcję Konfiguracja .

Adnotacje

Adnotacja @TimerTrigger w funkcji definiuje schedule użycie tego samego formatu ciągu co wyrażenia CRON. Adnotacja obsługuje następujące ustawienia:

Konfigurowanie

Dotyczy tylko modelu programowania języka Python w wersji 1.

W poniższej tabeli opisano właściwości, które można ustawić dla options obiektu przekazanego app.timer() do metody .

Właściwości opis
schedule Wyrażenie NCRONTAB lub wartość TimeSpan. Element TimeSpan może być używany tylko dla aplikacji funkcji działającej w planie usługi App Service. Możesz umieścić wyrażenie harmonogramu w ustawieniu aplikacji i ustawić tę właściwość na nazwę ustawienia aplikacji opakowaną w % znaki, jak w tym przykładzie: "%ScheduleAppSetting%".
runOnStartup Jeśli truefunkcja jest wywoływana po uruchomieniu środowiska uruchomieniowego. Na przykład środowisko uruchomieniowe jest uruchamiane, gdy aplikacja funkcji wznawia się po przejściu w stan bezczynności z powodu braku aktywności. gdy aplikacja funkcji zostanie uruchomiona ponownie z powodu zmian funkcji i gdy aplikacja funkcji zostanie skalowana w poziomie. Należy zachować ostrożność. parametr runOnStartup powinien rzadko być ustawiony na truewartość , szczególnie w środowisku produkcyjnym.
useMonitor Ustaw na wartość true lub false, aby wskazać, czy harmonogram powinien być monitorowany. Monitorowanie harmonogramu utrwala wystąpienia harmonogramu, aby pomóc w zapewnieniu prawidłowej konserwacji harmonogramu nawet po ponownym uruchomieniu wystąpień aplikacji funkcji. Jeśli nie ustawiono jawnie, wartością domyślną jest true harmonogramy z interwałem cyklu większym lub równym 1 minucie. W przypadku harmonogramów wyzwalających więcej niż raz na minutę wartość domyślna to false.

W poniższej tabeli opisano właściwości konfiguracji powiązania ustawione w pliku function.json .

właściwość function.json opis
type Musi być ustawiona wartość "timerTrigger". Ta właściwość jest ustawiana automatycznie podczas tworzenia wyzwalacza w witrynie Azure Portal.
direction Musi być ustawiona wartość "in". Ta właściwość jest ustawiana automatycznie podczas tworzenia wyzwalacza w witrynie Azure Portal.
name Nazwa zmiennej reprezentującej obiekt czasomierza w kodzie funkcji.
schedule Wyrażenie NCRONTAB lub wartość TimeSpan. Element TimeSpan może być używany tylko dla aplikacji funkcji działającej w planie usługi App Service. Możesz umieścić wyrażenie harmonogramu w ustawieniu aplikacji i ustawić tę właściwość na nazwę ustawienia aplikacji opakowaną w % znaki, jak w tym przykładzie: "%ScheduleAppSetting%".
runOnStartup Jeśli truefunkcja jest wywoływana po uruchomieniu środowiska uruchomieniowego. Na przykład środowisko uruchomieniowe jest uruchamiane, gdy aplikacja funkcji wznawia się po przejściu w stan bezczynności z powodu braku aktywności. gdy aplikacja funkcji zostanie uruchomiona ponownie z powodu zmian funkcji i gdy aplikacja funkcji zostanie skalowana w poziomie. Należy zachować ostrożność. parametr runOnStartup powinien rzadko być ustawiony na truewartość , szczególnie w środowisku produkcyjnym.
useMonitor Ustaw na wartość true lub false, aby wskazać, czy harmonogram powinien być monitorowany. Monitorowanie harmonogramu utrwala wystąpienia harmonogramu, aby pomóc w zapewnieniu prawidłowej konserwacji harmonogramu nawet po ponownym uruchomieniu wystąpień aplikacji funkcji. Jeśli nie ustawiono jawnie, wartością domyślną jest true harmonogramy z interwałem cyklu większym lub równym 1 minucie. W przypadku harmonogramów wyzwalających więcej niż raz na minutę wartość domyślna to false.

Podczas tworzenia aplikacji lokalnie dodaj ustawienia aplikacji w pliku local.settings.json w kolekcji Values .

Uwaga

Nie należy ustawiać parametru runOnStartup na true wartość w środowisku produkcyjnym. Użycie tego ustawienia sprawia, że kod jest wykonywany w bardzo nieprzewidywalnych czasach. W niektórych ustawieniach produkcyjnych te dodatkowe wykonania mogą spowodować znacznie wyższe koszty aplikacji hostowanych w planie Zużycie. Na przykład po włączeniu funkcji runOnStartup wyzwalacz jest wywoływany za każdym razem, gdy aplikacja funkcji jest skalowana. Przed włączeniem funkcji runOnStartup w środowisku produkcyjnym upewnij się, że w pełni rozumiesz zachowanie produkcyjne funkcji.

Zobacz sekcję Przykład, aby zapoznać się z kompletnymi przykładami.

Użycie

Po wywołaniu funkcji wyzwalacza czasomierza obiekt czasomierza jest przekazywany do funkcji. Poniższy kod JSON jest przykładową reprezentacją obiektu czasomierza.

{
    "Schedule":{
        "AdjustForDST": true
    },
    "ScheduleStatus": {
        "Last":"2016-10-04T10:15:00+00:00",
        "LastUpdated":"2016-10-04T10:16:00+00:00",
        "Next":"2016-10-04T10:20:00+00:00"
    },
    "IsPastDue":false
}
{
    "schedule":{
        "adjustForDST": true
    },
    "scheduleStatus": {
        "last":"2016-10-04T10:15:00+00:00",
        "lastUpdated":"2016-10-04T10:16:00+00:00",
        "next":"2016-10-04T10:20:00+00:00"
    },
    "isPastDue":false
}

Właściwość isPastDue jest true wtedy, gdy wywołanie bieżącej funkcji jest późniejsze niż zaplanowane. Na przykład ponowne uruchomienie aplikacji funkcji może spowodować pominięcie wywołania.

Wyrażenia NCRONTAB

Usługa Azure Functions używa biblioteki NCronTab do interpretowania wyrażeń NCRONTAB. Wyrażenie NCRONTAB jest podobne do wyrażenia CRON, z tą różnicą, że zawiera dodatkowe szóste pole na początku do użycia na potrzeby dokładności czasu w sekundach:

{second} {minute} {hour} {day} {month} {day-of-week}

Każde pole może mieć jeden z następujących typów wartości:

Typ Przykład Po wyzwoleniu
Określona wartość 0 5 * * * * Raz na godzinę dnia w minutach 5 każdej godziny
Wszystkie wartości (*) 0 * 5 * * * Co minutę w godzinie, w ciągu godziny 5
Zakres (- operator) 5-7 * * * * * Trzy razy na minutę — w sekundach od 5 do 7 w każdej minucie każdego dnia
Zestaw wartości (, operator) 5,8,10 * * * * * Trzy razy na minutę — w sekundach 5, 8 i 10 w każdej minucie każdego dnia
Wartość interwału (/ operator) 0 */5 * * * * 12 razy na godzinę — w sekundach 0 co 5 minutę każdego dnia

Aby określić miesiące lub dni, możesz użyć wartości liczbowych, nazw lub skrótów nazw:

  • W dniach wartości liczbowe to od 0 do 6, gdzie 0 zaczyna się od niedzieli.
  • Nazwy są w języku angielskim. Przykład: Monday, January.
  • Nazwy są niewrażliwe na wielkość liter.
  • Nazwy można skrócić. Zalecamy używanie trzech liter dla skrótów. Przykład: Mon, Jan.

Przykłady NCRONTAB

Poniżej przedstawiono kilka przykładów wyrażeń NCRONTAB, których można użyć dla wyzwalacza czasomierza w usłudze Azure Functions.

Przykład Po wyzwoleniu
0 */5 * * * * raz na pięć minut
0 0 * * * * raz w górnej części co godzinę
0 0 */2 * * * raz na dwie godziny
0 0 9-17 * * * raz na godzinę od 9:00 do 17:00
0 30 9 * * * o 9:30 codziennie
0 30 9 * * 1-5 o 9:30 co dzień powszedni
0 30 9 * Jan Mon o 9:30 co poniedziałek w styczniu

Uwaga

Wyrażenie NCRONTAB obsługuje zarówno pięć pól, jak i sześć formatów pól. Szósta pozycja pola to wartość sekundy umieszczona na początku wyrażenia. Jeśli wyrażenie CRON jest nieprawidłowe, test funkcji witryny Azure Portal wyświetli błąd 404, jeśli usługa Application Insights jest połączona z więcej szczegółów, zostaną tam zarejestrowane.

STREFY czasowe NCRONTAB

Liczby w wyrażeniu NCRONTAB odnoszą się do godziny i daty, a nie przedziału czasu. Na przykład 5 w hour polu odnosi się do 5:00, a nie co 5 godzin.

Domyślna strefa czasowa używana z wyrażeniami CRON to uniwersalny czas koordynowany (UTC). Aby utworzyć wyrażenie CRON na podstawie innej strefy czasowej, utwórz ustawienie aplikacji dla aplikacji funkcji o nazwie WEBSITE_TIME_ZONE.

Wartość tego ustawienia zależy od systemu operacyjnego i planu, na którym działa aplikacja funkcji.

System operacyjny Planowanie Wartość
Windows wszystkie Ustaw wartość na nazwę żądanej strefy czasowej podanej przez drugi wiersz z każdej pary podanej przez polecenie systemu Windows tzutil.exe /L
Linux Premium
Dedykowane
Ustaw wartość na nazwę żądanej strefy czasowej, jak pokazano w bazie danych tz.

Uwaga

WEBSITE_TIME_ZONE i TZ nie są obecnie obsługiwane w przypadku uruchamiania w systemie Linux w planie zużycie. W takim przypadku ustawienie WEBSITE_TIME_ZONE lub TZ może utworzyć problemy związane z protokołem SSL i spowodować, że metryki przestaną działać dla aplikacji.

Na przykład czas wschodni w Stanach Zjednoczonych (reprezentowany przez Eastern Standard Time (Windows) lub America/New_York (Linux)) obecnie używa czasu UTC-05:00 w czasie standardowym i UTC-04:00 w czasie letnim. Aby uruchomić wyzwalacz czasomierza o godzinie 10:00 czasu wschodniego każdego dnia, utwórz ustawienie aplikacji dla aplikacji funkcji o nazwie WEBSITE_TIME_ZONE, ustaw wartość Eastern Standard Time (Windows) lub America/New_York (Linux), a następnie użyj następującego wyrażenia NCRONTAB:

"0 0 10 * * *"

Gdy używasz WEBSITE_TIME_ZONE czasu jest dostosowywany do zmian czasu w określonej strefie czasowej, w tym czasu letniego i zmian w czasie standardowym.

przedział_czasu

Element TimeSpan może być używany tylko dla aplikacji funkcji działającej w planie usługi App Service.

W przeciwieństwie do wyrażenia TimeSpan NCRONTAB wartość określa interwał czasu między poszczególnymi wywołaniami funkcji. Gdy funkcja zostanie ukończona po uruchomieniu dłuższym niż określony interwał, czasomierz natychmiast wywołuje funkcję ponownie.

Wyrażony jako ciąg TimeSpan format ma hh:mm:ss hh wartość mniejszą niż 24. Gdy pierwsze dwie cyfry mają wartość 24 lub większą, format to dd:hh:mm. Oto kilka przykładów:

Przykład Po wyzwoleniu
"01:00:00" co godzinę
"00:01:00" co minutę
"25:00:00:00" co 25 dni
"1.00:00:00" Codziennie

Skalowanie w poziomie

Jeśli aplikacja funkcji skaluje się w poziomie do wielu wystąpień, tylko jedno wystąpienie funkcji wyzwalanej przez czasomierz jest uruchamiane we wszystkich wystąpieniach. Nie zostanie on ponownie wyzwolony, jeśli nadal jest uruchomione wybitne wywołanie.

Udostępnianie magazynu przez aplikacje funkcji

Jeśli udostępniasz konta magazynu w aplikacjach funkcji, które nie zostały wdrożone w usłudze App Service, może być konieczne jawne przypisanie identyfikatora hosta do każdej aplikacji.

Wersja usługi Functions Ustawienie
2.x (i nowsze) AzureFunctionsWebHost__hostid zmienna środowiskowa
1.x id w host.json

Można pominąć wartość identyfikującą lub ręcznie ustawić konfigurację identyfikacji każdej aplikacji funkcji na inną wartość.

Wyzwalacz czasomierza używa blokady magazynu, aby upewnić się, że istnieje tylko jedno wystąpienie czasomierza, gdy aplikacja funkcji skaluje w poziomie do wielu wystąpień. Jeśli dwie aplikacje funkcji współdzielą tę samą konfigurację identyfikującą, a każda z nich używa wyzwalacza czasomierza, tylko jeden czasomierz jest uruchamiany.

Zachowanie ponawiania prób

W przeciwieństwie do wyzwalacza kolejki wyzwalacz czasomierza nie ponawia próby po awarii funkcji. Gdy funkcja zakończy się niepowodzeniem, nie zostanie ponownie wywołana do następnego czasu zgodnie z harmonogramem.

Ręczne wywoływanie wyzwalacza czasomierza

Wyzwalacz czasomierza dla usługi Azure Functions udostępnia element webhook HTTP, który można wywołać w celu ręcznego wyzwolenia funkcji. Może to być bardzo przydatne w następujących scenariuszach.

  • Testowanie integracji
  • Zamiany miejsc w ramach testu weryfikacyjnego kompilacji lub działania rozgrzewki
  • Początkowe wdrożenie funkcji w celu natychmiastowego wypełnienia pamięci podręcznej lub tabeli odnośników w bazie danych

Aby uzyskać szczegółowe informacje na temat ręcznego wywoływania funkcji wyzwalanej przez czasomierz, zapoznaj się z instrukcjami ręcznego uruchamiania funkcji wyzwalanej przez protokół HTTP.

Rozwiązywanie problemów

Aby uzyskać informacje o tym, co zrobić, gdy wyzwalacz czasomierza nie działa zgodnie z oczekiwaniami, zobacz Badanie i raportowanie problemów z funkcjami wyzwalanymi przez czasomierz, które nie są wyzwalane.

Następne kroki