Public Class Customer
{
   public int CustomerId{get;set;}
   Public string CustomerName{get;set;}
}

public class RunParallel(List<Customer> namelessCustomers)
{
   Parallel.ForEach(namelessCustomers, (customer) =>{
      var customerName = CallAPIToReturnCustomerName(customer.CustomerId);
      customer.CustomerName = customerName
   }
}

Hi to customer.CustomerName=customerName sejf. Chcę zaktualizować listę klientów, aby każdy obiekt otrzymał nazwę klientów. Jeśli nie, jak mogę uzyskać coś takiego do pracy. Możesz także wyjaśnić, dlaczego nie byłoby to bezpieczne?

0
David 25 luty 2021, 10:27

3 odpowiedzi

Najlepsza odpowiedź

Po pierwsze, ciągi są niezmienne , a odniesienia są Atomic , dzięki czemu właściwość jest bezpieczna, to nie mówić, że jest to immunologiczne ze stałaków i danych wyścigi - choć nie wydaje się tutaj

Po drugie, dzwonisz do obciążenia obciążenia IO parallel.ForEach, co nie jest optymalne. Znaczenie, blokujesz i wiążysz puli wątków , które można skutecznie przeładować do portów uzupełniających IO. Prawdopodobnie po prostu lepiej pozwalasz na wywołanie API być async i przy użyciu Task.WhenAll

Przykład

public async Task<Customer> CallAPIToReturnCustomerNameAsync(int customerId) 
{
   ///await someThingAsyncHere();
}

...

async Task Process(Customer customer)
{
    customer.CustomerName = await CallAPIToReturnCustomerNameAsync(customer.CustomerId);
}

var tasks = namelessCustomers.Select(Process);
await Task.WhenAll(tasks);
4
halfer 1 marzec 2021, 01:28

Główne niebezpieczeństwa są równoległe czytanie / pisze lub pisze / pisze. Jeśli każdy obiekt ma dostęp tylko z pojedynczego wątku, byłoby to wątek z domyślnym, tj. Lista nie ma wielu kopii tego samego klienta, a nie ma innego wątku, który może uzyskać dostęp do listy klientów, gdy pętla jest uruchomiona.

Nawet jeśli występuje jednoczesny dostęp, jest to atomowy, dopóki typ jest typem odniesienia lub typ wartości jest mniejszy niż rodzimy całkowite, jak jest w tym przykładzie. Jest to jednak prawdą tylko dla pojedynczego dostępu do zapisu / zapisu, wszelkie działanie obejmujące wiele operacji nie byłyby bezpieczne.

2
JonasH 25 luty 2021, 07:43

Bezpieczeństwo nitki i współbieżność to dwa podejścia, które są godne uwagi wewnątrz dwóch sytuacji: 1- Jest jeden jeden krytyczny obszar, w którym mogą wejść równoległe czytelnicy / pisarze. (Nawet w programowaniu współbieżnym lub równoległym) przez jednoczesne programowanie, rozumiem wielokrotne i równoległość, miałem na myśli programowanie wielordzeniowe. 2- Pisarze powodują czytelników i imadło Versa. Na przykład musisz przeczytać i sprawdzić przed zapisem na jednym obszarze. Oba powyższe zasady mogą powodować warunki rasy i powinny być godne uwagi. W Twoim przypadku:

  • Nie masz rasy, ponieważ po prostu piszesz, a sekwencja nie jest ważna.
  • Nie masz znowu rasy, ponieważ piszesz w kilku obszarach i obszarach (własność różnych klientów) nie są udostępniane.

Uwaga: Warunek wyścigu nie jest związany z drogą / stosem / językiem programowania Multi-X i możesz mieć tę sytuację zarówno w programowaniu wielokrotnym, wielodzeniowym. Zalecam więc podwójne sprawdzenie kodu i znajdziesz krytyczne obszary i zapisu / zapisu lub zapisywać / przeczytać chwile. I znajdziesz tam nie ma :)

1
Amir 25 luty 2021, 10:30