biblioteka klienta Azure Service Bus dla platformy .NET — wersja 7.13.1
Azure Service Bus umożliwia tworzenie aplikacji korzystających z asynchronicznych wzorców obsługi komunikatów przy użyciu wysoce niezawodnej usługi do brokera komunikatów między producentami a konsumentami. Azure Service Bus zapewnia elastyczne, obsługiwane przez brokera komunikaty między klientem a serwerem oraz ustrukturyzowaną obsługą komunikatów typu pierwszy na pierwszym w poziomie (FIFO) oraz funkcje publikowania/subskrybowania przy użyciu złożonego routingu. Jeśli chcesz dowiedzieć się więcej o Azure Service Bus, warto przejrzeć artykuł: Co to jest Azure Service Bus?
Użyj biblioteki klienta dla Azure Service Bus, aby:
Transfer danych biznesowych: korzystaj z komunikatów w celu trwałej wymiany informacji, takich jak zamówienia sprzedaży lub zamówień zakupu, dzienniki lub przenoszenie zapasów.
Oddzielenie aplikacji: zwiększanie niezawodności i skalowalności aplikacji i usług, równoczesne zwalnianie nadawców i odbiorców z konieczności jednoczesnego bycia w trybie online.
Kontrolowanie sposobu przetwarzania komunikatów: obsługa tradycyjnych konkurencyjnych odbiorców dla komunikatów przy użyciu kolejek lub zezwalanie każdemu odbiorcy na własne wystąpienie komunikatu przy użyciu tematów i subskrypcji.
Implementowanie złożonych przepływów pracy: sesje komunikatów obsługują scenariusze wymagające porządkowania komunikatów lub odroczenia komunikatów.
Kod | źródłowy Pakiet (NuGet) | Dokumentacja referencyjna interfejsu | API Dokumentacja | produktu Przewodnik migracji | Przewodnik rozwiązywania problemów
Subskrypcja platformy Microsoft Azure: Do korzystania z usług platformy Azure, w tym Azure Service Bus, potrzebna jest subskrypcja. Jeśli nie masz istniejącego konta platformy Azure, możesz utworzyć konto bezpłatnej wersji próbnej lub skorzystać z korzyści subskrybenta MSDN podczas tworzenia konta.
Przestrzeń nazw usługi Service Bus: Aby korzystać z Azure Service Bus, musisz również mieć dostępną przestrzeń nazw. Jeśli nie znasz tworzenia zasobów platformy Azure, możesz skorzystać z przewodnika krok po kroku dotyczącego tworzenia przestrzeni nazw usługi Service Bus przy użyciu Azure Portal. W tym miejscu można również znaleźć szczegółowe instrukcje dotyczące używania interfejsu wiersza polecenia platformy Azure, Azure PowerShell lub szablonów usługi Azure Resource Manager (ARM) w celu utworzenia jednostki usługi Service Bus.
C# 8.0: Biblioteka klienta Azure Service Bus korzysta z nowych funkcji, które zostały wprowadzone w języku C# 8.0. Aby korzystać ze składni języka C# 8.0, zaleca się skompilowanie przy użyciu zestawu .NET Core SDK 3.0 lub nowszego
latest
z wersją języka .Użytkownicy programu Visual Studio, którzy chcą w pełni korzystać ze składni języka C# 8.0, muszą korzystać z programu Visual Studio 2019 lub nowszego. Program Visual Studio 2019, w tym bezpłatna wersja Community, można pobrać tutaj. Użytkownicy programu Visual Studio 2017 mogą korzystać ze składni języka C# 8, korzystając z pakietu NuGet Microsoft.Net.Compilers i ustawiając wersję języka, chociaż środowisko edycji może nie być idealne.
Nadal można używać biblioteki z poprzednimi wersjami języka C#, ale trzeba będzie zarządzać asynchronicznymi wyliczalnymi i asynchronicznymi członkami jednorazowymi ręcznie, zamiast korzystać z nowej składni. Nadal możesz kierować dowolną wersję platformy obsługiwaną przez zestaw .NET Core SDK, w tym wcześniejsze wersje platformy .NET Core lub .NET Framework. Aby uzyskać więcej informacji, zobacz: jak określić platformy docelowe.
Ważna uwaga: Aby skompilować lub uruchomić przykłady i przykłady bez modyfikacji, użycie języka C# 8.0 jest obowiązkowe. Nadal możesz uruchomić przykłady, jeśli zdecydujesz się dostosować je dla innych wersji językowych.
Aby szybko utworzyć potrzebne zasoby usługi Service Bus na platformie Azure i odebrać dla nich parametry połączenia, możesz wdrożyć nasz przykładowy szablon, klikając:
Zainstaluj bibliotekę klienta Azure Service Bus dla platformy .NET przy użyciu narzędzia NuGet:
dotnet add package Azure.Messaging.ServiceBus
Aby biblioteka klienta usługi Service Bus współdziałała z kolejką lub tematem, należy zrozumieć, jak nawiązać z nią połączenie i autoryzować je. Najprostszym sposobem jest użycie parametrów połączenia, które są tworzone automatycznie podczas tworzenia przestrzeni nazw usługi Service Bus. Jeśli nie znasz zasad dostępu współdzielonego na platformie Azure, możesz skorzystać z przewodnika krok po kroku, aby uzyskać parametry połączenia usługi Service Bus.
Po utworzeniu parametrów połączenia możesz uwierzytelnić klienta za pomocą niego.
// Create a ServiceBusClient that will authenticate using a connection string
string connectionString = "<connection_string>";
await using var client = new ServiceBusClient(connectionString);
Aby zobaczyć, jak uwierzytelniać się przy użyciu elementu Azure.Identity, wyświetl ten przykład.
Aby zobaczyć, jak zainicjować połączenie z niestandardowym punktem końcowym, wyświetl ten przykład.
Aby wstrzyknąć ServiceBusClient
jako zależność w aplikacji ASP.NET Core, zainstaluj integrację biblioteki klienta platformy Azure dla pakietu ASP.NET Core.
dotnet add package Microsoft.Extensions.Azure
Następnie zarejestruj klienta w metodzie Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddAzureClients(builder =>
{
builder.AddServiceBusClient(Configuration.GetConnectionString("ServiceBus"));
});
services.AddControllers();
}
Aby użyć powyższego kodu, dodaj go do konfiguracji:
{
"ConnectionStrings": {
"ServiceBus": "<connection_string>"
}
}
Aby uzyskać więcej informacji, zobacz Wstrzykiwanie zależności za pomocą zestawu Azure SDK dla platformy .NET.
Po zainicjowaniu ServiceBusClient
klasy można wchodzić w interakcje z podstawowymi typami zasobów w przestrzeni nazw usługi Service Bus, z których wiele może istnieć i na których odbywa się rzeczywista transmisja komunikatów, przestrzeń nazw często pełni rolę kontenera aplikacji:
Kolejka: umożliwia wysyłanie i odbieranie komunikatów. Często używane do komunikacji punkt-punkt.
Temat: W przeciwieństwie do kolejek tematy lepiej nadają się do scenariuszy publikowania/subskrybowania. Temat można wysłać do, ale wymaga subskrypcji, z której może być wiele równolegle, do użycia.
Subskrypcja: mechanizm do korzystania z tematu. Każda subskrypcja jest niezależna i otrzymuje kopię każdego komunikatu wysłanego do tematu. Reguły i filtry mogą służyć do dostosowywania komunikatów odbieranych przez określoną subskrypcję.
Aby uzyskać więcej informacji na temat tych zasobów, zobacz Co to jest Azure Service Bus?.
Aby korzystać z tych zasobów, należy zapoznać się z następującymi pojęciami dotyczącymi zestawu SDK:
Klient usługi Service Bus jest podstawowym interfejsem dla deweloperów korzystających z biblioteki klienta usługi Service Bus. Służy jako brama, z której nastąpi cała interakcja z biblioteką.
Nadawca usługi Service Bus jest w zakresie określonej kolejki lub tematu i jest tworzony przy użyciu klienta usługi Service Bus. Nadawca umożliwia wysyłanie komunikatów do kolejki lub tematu. Umożliwia również planowanie dostępności komunikatów do dostarczania w określonym dniu.
Odbiornik usługi Service Bus jest w zakresie określonej kolejki lub subskrypcji i jest tworzony przy użyciu klienta usługi Service Bus. Odbiornik umożliwia odbieranie komunikatów z kolejki lub subskrypcji. Umożliwia również rozliczanie komunikatów po ich odebraniu. Istnieją cztery sposoby rozliczania komunikatów:
- Ukończono — powoduje usunięcie komunikatu z kolejki lub tematu.
- Abandon — zwalnia blokadę odbiorcy w komunikacie, co umożliwia odbieranie komunikatu przez innych odbiorników.
- Odroczenie — odchyli wiadomość od odebrania w normalny sposób. Aby odbierać komunikaty odroczone, należy zachować numer sekwencji komunikatu.
- DeadLetter — przenosi komunikat do kolejki utraconych komunikatów. Uniemożliwi to ponowne odebranie komunikatu. Aby odbierać komunikaty z kolejki utraconych komunikatów, potrzebny jest odbiornik o zakresie do kolejki utraconych komunikatów.
Odbiornik sesji usługi Service Bus jest w zakresie określonej kolejki lub subskrypcji z włączoną obsługą sesji i jest tworzony przy użyciu klienta usługi Service Bus. Odbiornik sesji jest prawie identyczny z odbiornikiem standardowym, a różnica polega na tym, że operacje zarządzania sesjami są uwidoczniane, które mają zastosowanie tylko do jednostek z obsługą sesji. Operacje te obejmują pobieranie i ustawianie stanu sesji, a także odnawianie blokad sesji.
Procesor usługi Service Bus jest w zakresie określonej kolejki lub subskrypcji i jest tworzony przy użyciu klienta usługi Service Bus. Element
ServiceBusProcessor
można traktować jako abstrakcję wokół zestawu odbiorników. Używa modelu wywołania zwrotnego, aby umożliwić określenie kodu po odebraniu komunikatu i wystąpieniu wyjątku. Oferuje automatyczne uzupełnianie przetworzonych komunikatów, automatyczne odnawianie blokady komunikatów i równoczesne wykonywanie procedur obsługi zdarzeń określonych przez użytkownika. Ze względu na zestaw funkcji powinien on być narzędziem do pisania aplikacji odbieranych z jednostek usługi Service Bus. Usługa ServiceBusReceiver jest zalecana w przypadku bardziej złożonych scenariuszy, w których procesor nie może zapewnić precyzyjnej kontroli, której można oczekiwać bezpośrednio podczas korzystania z klasy ServiceBusReceiver.Procesor sesji usługi Service Bus jest w zakresie określonej kolejki lub subskrypcji z włączoną obsługą sesji i jest tworzony przy użyciu klienta usługi Service Bus. Procesor sesji jest prawie identyczny z procesorem standardowym, a różnica polega na tym, że operacje zarządzania sesjami są uwidocznione, które mają zastosowanie tylko do jednostek z obsługą sesji.
Aby uzyskać więcej pojęć i głębszą dyskusję, zobacz: Funkcje zaawansowane usługi Service Bus.
ServiceBusClient
Nadawcy, odbiorcy i procesory są bezpieczne do buforowania i używania jako pojedynczego elementu w okresie istnienia aplikacji, co jest najlepszym rozwiązaniem w przypadku regularnego wysyłania lub odbierania komunikatów. Są one odpowiedzialne za efektywne zarządzanie siecią, procesorem CPU i użyciem pamięci, pracując nad utrzymaniem niskiego użycia w okresach braku aktywności.
Te typy są jednorazowe i wymagają wywołania DisposeAsync
metody lub CloseAsync
w celu upewnienia się, że zasoby sieciowe i inne niezarządzane obiekty są prawidłowo czyszczone. Należy pamiętać, że gdy ServiceBusClient
wystąpienie zostanie usunięte, automatycznie zamknie i wyczyści wszystkich nadawców, odbiorników i procesorów, które zostały utworzone przy jego użyciu.
Gwarantujemy, że wszystkie metody wystąpienia klienta są bezpieczne wątkowo i niezależne od siebie (wytyczne). Dzięki temu zalecenie ponownego obsługi wystąpień klienta jest zawsze bezpieczne, nawet w wątkach.
Opcje | klienta Diagnostyka | Szyderczy
- Wysyłanie i odbieranie komunikatu
- Wysyłanie partii komunikatów
- Odbieranie partii komunikatów
- Ukończ komunikat
- Porzucanie wiadomości
- Odroczenie wiadomości
- Wiadomość o martwym punkcie
- Korzystanie z procesora
- Uwierzytelnianie przy użyciu usługi Azure.Identity
- Praca z sesjami
- Więcej przykładów
Wysyłanie komunikatów jest wykonywane przy użyciu elementu ServiceBusSender
. Odbieranie jest wykonywane przy użyciu elementu ServiceBusReceiver
.
string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);
// create the sender
ServiceBusSender sender = client.CreateSender(queueName);
// create a message that we can send. UTF-8 encoding is used when providing a string.
ServiceBusMessage message = new ServiceBusMessage("Hello world!");
// send the message
await sender.SendMessageAsync(message);
// create a receiver that we can use to receive the message
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
// the received message is a different type as it contains some service set properties
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
// get the message body as a string
string body = receivedMessage.Body.ToString();
Console.WriteLine(body);
Istnieją dwa sposoby wysyłania kilku komunikatów jednocześnie. Pierwszy sposób wykonywania tej czynności korzysta z bezpiecznego przetwarzania wsadowego. Dzięki bezpiecznemu wsadowi można utworzyć obiekt, który umożliwi próbę ServiceBusMessageBatch
dodania komunikatów pojedynczo do partii przy użyciu TryAdd
metody . Jeśli komunikat nie może zmieścić się w partii, TryAdd
zwróci wartość false.
// add the messages that we plan to send to a local queue
Queue<ServiceBusMessage> messages = new Queue<ServiceBusMessage>();
messages.Enqueue(new ServiceBusMessage("First message"));
messages.Enqueue(new ServiceBusMessage("Second message"));
messages.Enqueue(new ServiceBusMessage("Third message"));
// create a message batch that we can send
// total number of messages to be sent to the Service Bus queue
int messageCount = messages.Count;
// while all messages are not sent to the Service Bus queue
while (messages.Count > 0)
{
// start a new batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();
// add the first message to the batch
if (messageBatch.TryAddMessage(messages.Peek()))
{
// dequeue the message from the .NET queue once the message is added to the batch
messages.Dequeue();
}
else
{
// if the first message can't fit, then it is too large for the batch
throw new Exception($"Message {messageCount - messages.Count} is too large and cannot be sent.");
}
// add as many messages as possible to the current batch
while (messages.Count > 0 && messageBatch.TryAddMessage(messages.Peek()))
{
// dequeue the message from the .NET queue as it has been added to the batch
messages.Dequeue();
}
// now, send the batch
await sender.SendMessagesAsync(messageBatch);
// if there are any remaining messages in the .NET queue, the while loop repeats
}
Drugi sposób używa SendMessagesAsync
przeciążenia, które akceptuje IEnumerable .ServiceBusMessage
W tej metodzie podejmiemy próbę dopasowania wszystkich dostarczonych komunikatów w jednej partii komunikatów, którą wyślemy do usługi. Jeśli komunikaty są zbyt duże, aby zmieścić się w jednej partii, operacja zgłosi wyjątek.
IList<ServiceBusMessage> messages = new List<ServiceBusMessage>();
messages.Add(new ServiceBusMessage("First"));
messages.Add(new ServiceBusMessage("Second"));
// send the messages
await sender.SendMessagesAsync(messages);
// create a receiver that we can use to receive the messages
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
// the received message is a different type as it contains some service set properties
// a batch of messages (maximum of 2 in this case) are received
IReadOnlyList<ServiceBusReceivedMessage> receivedMessages = await receiver.ReceiveMessagesAsync(maxMessages: 2);
// go through each of the messages received
foreach (ServiceBusReceivedMessage receivedMessage in receivedMessages)
{
// get the message body as a string
string body = receivedMessage.Body.ToString();
}
Aby usunąć komunikat z kolejki lub subskrypcji, możemy wywołać metodę CompleteAsync
.
string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);
// create the sender
ServiceBusSender sender = client.CreateSender(queueName);
// create a message that we can send
ServiceBusMessage message = new ServiceBusMessage("Hello world!");
// send the message
await sender.SendMessageAsync(message);
// create a receiver that we can use to receive and settle the message
ServiceBusReceiver receiver = client.CreateReceiver(queueName);
// the received message is a different type as it contains some service set properties
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
// complete the message, thereby deleting it from the service
await receiver.CompleteMessageAsync(receivedMessage);
Porzucanie komunikatu zwalnia blokadę odbiornika, która umożliwia odbieranie komunikatu przez ten lub inne odbiorniki.
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
// abandon the message, thereby releasing the lock and allowing it to be received again by this or other receivers
await receiver.AbandonMessageAsync(receivedMessage);
Odroczenie komunikatu uniemożliwi ponowne odbieranie go przy użyciu ReceiveMessageAsync
metod or ReceiveMessagesAsync
. Zamiast tego istnieją oddzielne metody i ReceiveDeferredMessagesAsync
odbieranie odroczonych komunikatówReceiveDeferredMessageAsync
.
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
// defer the message, thereby preventing the message from being received again without using
// the received deferred message API.
await receiver.DeferMessageAsync(receivedMessage);
// receive the deferred message by specifying the service set sequence number of the original
// received message
ServiceBusReceivedMessage deferredMessage = await receiver.ReceiveDeferredMessageAsync(receivedMessage.SequenceNumber);
Nieaktywne wysyłanie wiadomości jest podobne do odroczenia z jedną główną różnicą jest to, że wiadomości będą automatycznie nieaktywne przez usługę po otrzymaniu określonej liczby razy. Aplikacje mogą zdecydować się ręcznie na komunikaty o utraconych wiadomościach na podstawie ich wymagań. Gdy wiadomość jest martwa, została ona rzeczywiście przeniesiona do kolejki podrzędnej oryginalnej kolejki. Należy pamiętać, że element ServiceBusReceiver
jest używany do odbierania komunikatów z kolejki utraconych wiadomości niezależnie od tego, czy kolejka główna jest włączona w sesji.
ServiceBusReceivedMessage receivedMessage = await receiver.ReceiveMessageAsync();
// Dead-letter the message, thereby preventing the message from being received again without receiving from the dead letter queue.
// We can optionally pass a dead letter reason and dead letter description to further describe the reason for dead-lettering the message.
await receiver.DeadLetterMessageAsync(receivedMessage, "sample reason", "sample description");
// receive the dead lettered message with receiver scoped to the dead letter queue.
ServiceBusReceiver dlqReceiver = client.CreateReceiver(queueName, new ServiceBusReceiverOptions
{
SubQueue = SubQueue.DeadLetter
});
ServiceBusReceivedMessage dlqMessage = await dlqReceiver.ReceiveMessageAsync();
// The reason and the description that we specified when dead-lettering the message will be available in the received dead letter message.
string reason = dlqMessage.DeadLetterReason;
string description = dlqMessage.DeadLetterErrorDescription;
Aby uzyskać więcej informacji, zobacz omówienie kolejek komunikatów utraconych w usłudze ServiceBus.
Można ServiceBusProcessor
traktować jako abstrakcję wokół zestawu odbiorników. Używa ona modelu wywołania zwrotnego, aby umożliwić określenie kodu po odebraniu komunikatu i wystąpieniu wyjątku. Oferuje automatyczne uzupełnianie przetworzonych komunikatów, automatyczne odnawianie blokady komunikatów i współbieżne wykonywanie procedur obsługi zdarzeń określonych przez użytkownika. Ze względu na zestaw funkcji powinien on być narzędziem do pisania aplikacji odbieranych z jednostek usługi Service Bus. Usługa ServiceBusReceiver jest zalecana w przypadku bardziej złożonych scenariuszy, w których procesor nie jest w stanie zapewnić szczegółowej kontroli, której można oczekiwać bezpośrednio podczas korzystania z usługi ServiceBusReceiver.
string connectionString = "<connection_string>";
string queueName = "<queue_name>";
// since ServiceBusClient implements IAsyncDisposable we create it with "await using"
await using var client = new ServiceBusClient(connectionString);
// create the sender
ServiceBusSender sender = client.CreateSender(queueName);
// create a set of messages that we can send
ServiceBusMessage[] messages = new ServiceBusMessage[]
{
new ServiceBusMessage("First"),
new ServiceBusMessage("Second")
};
// send the message batch
await sender.SendMessagesAsync(messages);
// create the options to use for configuring the processor
var options = new ServiceBusProcessorOptions
{
// By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler
// Set AutoCompleteMessages to false to [settle messages](/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own.
// In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message.
AutoCompleteMessages = false,
// I can also allow for multi-threading
MaxConcurrentCalls = 2
};
// create a processor that we can use to process the messages
await using ServiceBusProcessor processor = client.CreateProcessor(queueName, options);
// configure the message and error handler to use
processor.ProcessMessageAsync += MessageHandler;
processor.ProcessErrorAsync += ErrorHandler;
async Task MessageHandler(ProcessMessageEventArgs args)
{
string body = args.Message.Body.ToString();
Console.WriteLine(body);
// we can evaluate application logic and use that to determine how to settle the message.
await args.CompleteMessageAsync(args.Message);
}
Task ErrorHandler(ProcessErrorEventArgs args)
{
// the error source tells me at what point in the processing an error occurred
Console.WriteLine(args.ErrorSource);
// the fully qualified namespace is available
Console.WriteLine(args.FullyQualifiedNamespace);
// as well as the entity path
Console.WriteLine(args.EntityPath);
Console.WriteLine(args.Exception.ToString());
return Task.CompletedTask;
}
// start processing
await processor.StartProcessingAsync();
// since the processing happens in the background, we add a Console.ReadKey to allow the processing to continue until a key is pressed.
Console.ReadKey();
Biblioteka tożsamości platformy Azure zapewnia łatwą obsługę usługi Azure Active Directory na potrzeby uwierzytelniania.
// Create a ServiceBusClient that will authenticate through Active Directory
string fullyQualifiedNamespace = "yournamespace.servicebus.windows.net";
await using var client = new ServiceBusClient(fullyQualifiedNamespace, new DefaultAzureCredential());
Sesje zapewniają mechanizm grupowania powiązanych komunikatów. Aby korzystać z sesji, musisz pracować z jednostką z obsługą sesji.
Zapoznaj się z przewodnikiem rozwiązywania problemów z usługą Service Bus.
Poza omówionymi scenariuszami wprowadzającymi biblioteka klienta Azure Service Bus oferuje obsługę dodatkowych scenariuszy, które ułatwiają korzystanie z pełnego zestawu funkcji usługi Azure Service Bus. Aby ułatwić zapoznanie się z niektórymi z tych scenariuszy, biblioteka kliencka usługi Service Bus oferuje projekt przykładów, który służy jako ilustracja dla typowych scenariuszy. Aby uzyskać szczegółowe informacje, zobacz przykłady README .
W tym projekcie zachęcamy do współtworzenia i zgłaszania sugestii. Współtworzenie w większości przypadków wymaga zgody na umowę licencyjną dotyczącą współautorów (CLA, Contributor License Agreement), zgodnie z którą współautor ma prawo udzielić i faktycznie udziela nam praw do używania wytworzonej przez siebie zawartości. Aby uzyskać szczegółowe informacje, odwiedź stronę https://cla.microsoft.com.
Po przesłaniu żądania ściągnięcia robot CLA automatycznie określi, czy musisz przekazać umowę CLA, i doda odpowiednie informacje do tego żądania (na przykład etykietę czy komentarz). Po prostu postępuj zgodnie z instrukcjami robota. Wystarczy zrobić to raz dla wszystkich repozytoriów, w przypadku których jest używana nasza umowa CLA.
W tym projekcie przyjęto Kodeks postępowania oprogramowania Open Source firmy Microsoft. Aby uzyskać więcej informacji, zobacz Często zadawane pytania dotyczące kodeksu postępowania lub skontaktuj się z opencode@microsoft.com dodatkowymi pytaniami lub komentarzami.
Aby uzyskać więcej informacji, zobacz nasz przewodnik dotyczący współtworzenia .