C# 修改并发容器中存储的元素时是否需要同步对象?
我有一个简单的课程:C# 修改并发容器中存储的元素时是否需要同步对象?,c#,.net,multithreading,C#,.net,Multithreading,我有一个简单的课程: public class TaskResult { public TaskResult() { CompletedSoFar = 0; Done = false; } [DataMember(Order = 0)] public int CompletedSoFar { get; set; } [DataMember(Order = 1)] public bool Done { ge
public class TaskResult
{
public TaskResult()
{
CompletedSoFar = 0;
Done = false;
}
[DataMember(Order = 0)]
public int CompletedSoFar { get; set; }
[DataMember(Order = 1)]
public bool Done { get; set; }
}
其类型的对象存储在ConcurrentDictionary中:
private static ConcurrentDictionary<Guid, TaskResult> _results;
我是否可以在没有同步对象的情况下修改值(即CompletedSoFar、Done)?如果尝试,是否会引发异常?由于您正在修改本机类型(整数),因此我不希望出现异常,这些类型无法锁定,并且可以在多个线程上安全访问。但是,在多个线程中更改此类(状态)类型时应小心,因为这可能会以意外的方式更改行为,并且很难跟踪在修改它们时不会引发异常。然后,您可以(技术上)这样做,但我建议您(如果可能)创建一些可以管理的“同步对象”(阻止/允许)对此特定对象进行更改,并且能够(出于调试目的)存储更改和调用者。此外,如果您想更改其他非本机类型,此对象将派上用场,因此这是代码扩展性的良好实践
public TaskResult DoWork(int[] ids)
{
var cancelSource = new CancellationTokenSource();
var result = new TaskResult();
_results[Guid.NewGuid()] = result;
var task = System.Threading.Tasks.Task.Factory.StartNew(() =>
{
try
{
foreach (var id in ids)
{
cancelSource.Token.ThrowIfCancellationRequested();
// Do work...
result.CompletedSoFar++; // Increment work completed so far
}
result.Done = true; // Work now done
}
catch
{
throw;
}
}, cancelSource.Token);
return result;
}