Dav*_*vid 0 c# multithreading thread-safety .net-5
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
}
}
Run Code Online (Sandbox Code Playgroud)
嗨是customer.CustomerName=customerName
线程安全的。我想要的是更新客户列表,以便每个对象都获得客户名称。如果不是,我怎么能得到这样的工作。另外你能解释一下为什么这不是线程安全的吗?
首先,字符串是不可变的,引用是原子的,所以属性是线程安全的,这并不是说它不受陈旧值和数据竞争的影响——尽管这里似乎不是这种情况
其次,你调用一个IO工作量中parallel.ForEach
这是不是最佳的。这意味着,您正在阻塞和占用线程池线程,这些线程可以有效地卸载到 IO 完成端口。您可能最好让 API 调用成为async
,并使用Task.WhenAll
例子
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);
Run Code Online (Sandbox Code Playgroud)