Przenoszenie
W tym temacie opisano transfer w modelu śledzenia działań programu Windows Communication Foundation (WCF).
Definicja transferu
Transfery między działaniami reprezentują relacje przyczynowe między zdarzeniami w powiązanych działaniach w punktach końcowych. Dwa działania są związane z transferami, gdy przepływy sterowania między tymi działaniami, na przykład metoda przechodzi przez granice działania. W programie WCF, gdy bajty są przychodzące w usłudze, działanie Nasłuchiwanie at jest przenoszone do działania Odbieranie bajtów, w którym jest tworzony obiekt komunikatu. Aby zapoznać się z listą scenariuszy kompleksowego śledzenia oraz ich odpowiednich projektów działań i śledzenia, zobacz Scenariusze kompleksowego śledzenia.
Aby emitować ślady transferu, użyj ActivityTracing
ustawienia w źródle śledzenia, jak pokazano w poniższym kodzie konfiguracji.
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
Używanie transferu do korelowania działań w punktach końcowych
Działania i transfery umożliwiają użytkownikowi probabilistically zlokalizowanie głównej przyczyny błędu. Na przykład, jeśli transferujemy tam i z powrotem między działaniami M i N odpowiednio w składnikach M i N, a awaria wystąpi w N bezpośrednio po przeniesieniu z powrotem do M, możemy wyciągnąć wniosek, że prawdopodobnie jest to spowodowane przekazywaniem danych z powrotem do M.
Ślad transferu jest emitowany z działania M do działania N, gdy istnieje przepływ kontroli między M i N. Na przykład N wykonuje pewną pracę dla języka M z powodu wywołania metody przekraczania granic działań. N może już istnieć lub został utworzony. N jest wywoływany przez M, gdy N jest nowym działaniem, które wykonuje jakąś pracę dla języka M.
Transfer z M do N może nie zostać przeniesiony z powrotem z N do M. Jest to spowodowane tym, że M może zduplikować niektóre prace w N i nie śledzić, gdy N zakończy tę pracę. W rzeczywistości język M może zakończyć działanie, zanim N zakończy swoje zadanie. Dzieje się tak w działaniu "Open ServiceHost" (M), które powoduje zduplikowanie działań odbiornika (N), a następnie kończy działanie. Przeniesienie z N do M oznacza, że N zakończył pracę związaną z M.
N może nadal wykonywać inne przetwarzanie niepowiązane z M, na przykład istniejące działanie wystawcy uwierzytelniania (N), które utrzymuje odbieranie żądań logowania (M) z różnych działań logowania.
Relacja zagnieżdżania nie musi istnieć między działaniami M i N. Może się to zdarzyć z dwóch powodów. Po pierwsze, gdy działanie M nie monitoruje rzeczywistego przetwarzania wykonywanego w N, chociaż M zainicjował N. Po drugie, gdy N już istnieje.
Przykład transferów
Poniżej wymieniono dwa przykłady transferu.
Podczas tworzenia hosta usługi konstruktor uzyskuje kontrolę z kodu wywołującego lub wywołuje kod transferuje do konstruktora. Po zakończeniu wykonywania konstruktora zwraca kontrolkę do kodu wywołującego lub konstruktor przekazuje go z powrotem do kodu wywołującego. Jest to przypadek relacji zagnieżdżonej.
Gdy odbiornik zacznie przetwarzać dane transportu, tworzy nowy wątek i przekazuje do działania Odbieraj bajty odpowiedni kontekst do przetwarzania, przekazywania kontroli i danych. Po zakończeniu przetwarzania żądania w tym wątku działanie Odbierz bajty nie przekazuje niczego z powrotem do odbiornika. W tym przypadku mamy transfer, ale nie przenosimy z nowego działania wątku. Te dwa działania są powiązane, ale nie są zagnieżdżone.
Sekwencja transferu działań
Dobrze sformułowana sekwencja transferu działań obejmuje następujące kroki.
Rozpocznij nowe działanie, które składa się z wybierania nowego identyfikatora gAId.
Emituj ślad transferu do tego nowego identyfikatora gAId z bieżącego identyfikatora działania
Ustawianie nowego identyfikatora w protokole TLS
Emituj ślad rozpoczęcia, aby wskazać początek nowego działania.
Powrót do oryginalnego działania składa się z następujących elementów:
Emituj ślad transferu do oryginalnego identyfikatora gAId
Emituj ślad zatrzymania, aby wskazać koniec nowego działania
Ustaw protokół TLS na stary identyfikator gAId.
W poniższym przykładzie kodu pokazano, jak to zrobić. W tym przykładzie przyjęto założenie, że podczas przesyłania do nowego działania jest wykonywane wywołanie blokujące i obejmuje ślady wstrzymania/wznowienia.
// 0. Create a trace source
TraceSource ts = new TraceSource("myTS");
// 1. remember existing ("ambient") activity for clean up
Guid oldGuid = Trace.CorrelationManager.ActivityId;
// this will be our new activity
Guid newGuid = Guid.NewGuid();
// 2. call transfer, indicating that we are switching to the new AID
ts.TraceTransfer(667, "Transferring.", newGuid);
// 3. Suspend the current activity.
ts.TraceEvent(TraceEventType.Suspend, 667, "Suspend: Activity " + i-1);
// 4. set the new AID in TLS
Trace.CorrelationManager.ActivityId = newGuid;
// 5. Emit the start trace
ts.TraceEvent(TraceEventType.Start, 667, "Boundary: Activity " + i);
// trace something
ts.TraceEvent(TraceEventType.Information, 667, "Hello from activity " + i);
// Perform Work
// some work.
// Return
ts.TraceEvent(TraceEventType.Information, 667, "Work complete on activity " + i);
// 6. Emit the transfer returning to the original activity
ts.TraceTransfer(667, "Transferring Back.", oldGuid);
// 7. Emit the End trace
ts.TraceEvent(TraceEventType.Stop, 667, "Boundary: Activity " + i);
// 8. Change the tls variable to the original AID
Trace.CorrelationManager.ActivityId = oldGuid;
// 9. Resume the old activity
ts.TraceEvent(TraceEventType.Resume, 667, "Resume: Activity " + i-1);