通过多个线程设置对象的属性
Setting properties from an object over multiple threads
我会尽力说明情况。
public class A
{
Int64 Id { get; set; }
Decimal Foo { get; set; }
}
public class B
{
Int64 Id { get; set; }
Decimal Bar { get; set; }
}
public class C
{
Int64 Id { get; set; }
Decimal? Foo { get; set; }
Decimal? Bar { get; set; }
}
public class test
{
ConcurrentDictionary<Int64, C> dictionary { get; set; }
List<A> listA { get; set; }
List<B> listB { get; set; }
}
listA 和 listB 各包含 500 万个对象。
所以我所做的是,我在单独的线程上循环遍历 listA 和 listB。
我检查字典是否包含 id,然后获取值并设置匹配 属性.
所以我的问题是,这是线程安全的吗?如果不是,让它成为线程安全的最佳方法是什么
还有一件事:
- listA 和 listB 中没有重复项。所以我只设置了任何对象C的属性一次。
使用虚拟数据的示例:
List<A> listA = new List<A>
{
new A { Id = 1, Foo = 5 },
new A { Id = 2, Foo = 10 },
new A { Id = 3, Foo = 100 }
};
List<B> listB = new List<B>
{
new A { Id = 1, Bar = 3 },
new A { Id = 2, Bar = 2 },
new A { Id = 3, Bar = 1 }
};
ConcurrentDictionary<Int64, C> dictionary = new ConcurrentDictionary<Int64, C>
{
Keys = {1, 2, 3},
Values = { new C { Id = 1 }, new C { Id = 2 }, new C { Id = 3 } }
};
之后我的字典会有这些 key/value 对:
Key = 1 , value = object of class C with properties : Id = 1, Foo = 5, Bar = 3,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 10, Bar = 2,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 100, Bar = 1
如果您在循环中所做的只是访问已在并发字典中的对象 C,并分别设置属性 Foo 和 Bar,那么是的,这应该是线程安全的。
如果您在 ConcurrentDictionary 中插入或删除项目,只要您正确使用 ConcurrentDictionary,那也应该是线程安全的。
ConcurrentDictionary 是线程安全的。
https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx
表示可以由多个线程同时访问的 key/value 对的线程安全集合。
因此您应该能够从任意数量的线程访问它。
但是有一个问题
假设您的字典是空的,两个线程都检查具有目标 ID 的对象是否存在,如果不存在则继续添加一个新对象,这两个线程可能会尝试添加相同的新对象物品。因此,您的字典必须已经包含对象,否则您将不得不使用锁。
我会尽力说明情况。
public class A
{
Int64 Id { get; set; }
Decimal Foo { get; set; }
}
public class B
{
Int64 Id { get; set; }
Decimal Bar { get; set; }
}
public class C
{
Int64 Id { get; set; }
Decimal? Foo { get; set; }
Decimal? Bar { get; set; }
}
public class test
{
ConcurrentDictionary<Int64, C> dictionary { get; set; }
List<A> listA { get; set; }
List<B> listB { get; set; }
}
listA 和 listB 各包含 500 万个对象。
所以我所做的是,我在单独的线程上循环遍历 listA 和 listB。 我检查字典是否包含 id,然后获取值并设置匹配 属性.
所以我的问题是,这是线程安全的吗?如果不是,让它成为线程安全的最佳方法是什么
还有一件事:
- listA 和 listB 中没有重复项。所以我只设置了任何对象C的属性一次。
使用虚拟数据的示例:
List<A> listA = new List<A>
{
new A { Id = 1, Foo = 5 },
new A { Id = 2, Foo = 10 },
new A { Id = 3, Foo = 100 }
};
List<B> listB = new List<B>
{
new A { Id = 1, Bar = 3 },
new A { Id = 2, Bar = 2 },
new A { Id = 3, Bar = 1 }
};
ConcurrentDictionary<Int64, C> dictionary = new ConcurrentDictionary<Int64, C>
{
Keys = {1, 2, 3},
Values = { new C { Id = 1 }, new C { Id = 2 }, new C { Id = 3 } }
};
之后我的字典会有这些 key/value 对:
Key = 1 , value = object of class C with properties : Id = 1, Foo = 5, Bar = 3,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 10, Bar = 2,
Key = 1 , value = object of class C with properties : Id = 1, Foo = 100, Bar = 1
如果您在循环中所做的只是访问已在并发字典中的对象 C,并分别设置属性 Foo 和 Bar,那么是的,这应该是线程安全的。
如果您在 ConcurrentDictionary 中插入或删除项目,只要您正确使用 ConcurrentDictionary,那也应该是线程安全的。
ConcurrentDictionary 是线程安全的。
https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx 表示可以由多个线程同时访问的 key/value 对的线程安全集合。
因此您应该能够从任意数量的线程访问它。 但是有一个问题
假设您的字典是空的,两个线程都检查具有目标 ID 的对象是否存在,如果不存在则继续添加一个新对象,这两个线程可能会尝试添加相同的新对象物品。因此,您的字典必须已经包含对象,否则您将不得不使用锁。