Tag:

可观察对象的同步机制

让我们假设我们必须同步对共享资源的读/写访问。 多个线程将在读取和写入时访问该资源(大多数时间用于读取,有时用于写入)。 让我们假设每次写入总是会触发读操作(对象是可观察的)。 对于这个例子,我会想象一个像这样的类(原谅语法和风格,它仅用于说明目的): class Container { public ObservableCollection Operands; public ObservableCollection Results; } 我很想将ReadWriterLockSlim用于此目的而且我将它放在Container级别(想象对象不那么简单,一个读/写操作可能涉及多个对象): public ReadWriterLockSlim Lock; Operand和Result实现对于此示例没有意义。 现在让我们设想一些观察Operands代码,并生成一个放入Results : void AddNewOperand(Operand operand) { try { _container.Lock.EnterWriteLock(); _container.Operands.Add(operand); } finally { _container.ExitReadLock(); } } 我们的hypotetical观察者会做类似的事情,但是要使用一个新元素,它将使用EnterReadLock()锁定以获取操作数,然后使用EnterWriteLock()来添加结果(让我省略代码)。 这会因为递归而产生exception,但是如果我设置了LockRecursionPolicy.SupportsRecursion那么我只需将代码打开到LockRecursionPolicy.SupportsRecursion (来自MSDN ): 默认情况下,使用LockRecursionPolicy.NoRecursion标志创建ReaderWriterLockSlim的新实例,并且不允许递归。 建议对所有新开发使用此默认策略,因为递归会引入不必要的复杂性并使您的代码更容易出现死锁 。 为清楚起见,我重复相关部分: 递归[…]使您的代码更容易出现死锁。 如果我对LockRecursionPolicy.SupportsRecursion没有错,如果从同一个线程我问一个,比如读锁定然后别人要求写锁定然后我会有一个死锁然后MSDN说的有意义。 此外,递归也会以可测量的方式降低性能(如果我使用的是ReadWriterLockSlim而不是ReadWriterLock或Monitor ,则不是我想要的)。 问题(S) 最后我的问题是(请注意我不是在寻找关于通用同步机制的讨论,我知道这个生成器/ observable / observer场景有什么问题 ): 在这种情况下有什么好处? 为了避免ReadWriterLockSlim支持Monitor […]

Application.LoadComponent的线程错误(密钥已存在)

MSDN说System.Windows.Application的公共静态成员是线程安全的。 但是当我尝试使用多个线程运行我的应用程序时,我得到以下exception: ArgumentException: An entry with the same key already exists. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.SortedList`2.Add(TKey key, TValue value) at System.IO.Packaging.Package.AddIfNoPrefixCollisionDetected(ValidatedPartUri partUri, PackagePart part) at System.IO.Packaging.Package.GetPartHelper(Uri partUri) at System.IO.Packaging.Package.GetPart(Uri partUri) at System.Windows.Application.GetResourceOrContentPart(Uri uri) at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties) at System.Windows.Application.LoadComponent(Uri resourceLocator) 以下调用发生exception: genericResources = (ResourceDictionary)Application.LoadComponent(new Uri(“/Themes/Generic.xaml”, UriKind.Relative)); 该应用程序在单个线程上工作正常,甚至在两个或三个上。 当我从5点起床后,每次都会收到错误。 难道我做错了什么? 我该怎么做才能解决这个问题?

String类中的线程安全性

使用String类从本地变量构建字符串是否安全,如下面的方法一样? 假设从多个线程调用以下方法。 public static string WriteResult(int value, string name) { return string.Format(“Result: value={0} name={1}”, value, name); } public static string WriteResult2(int value, string name) { return “Result: value=” + value + ” name=” + name; } 或者我是否需要使用StringBuilder来确保线程安全?

Interlocked是否保证C#中其他线程的可见性,还是仍然需要使用volatile?

我一直在阅读类似问题的答案,但我仍然有点困惑……亚伯有一个很好的答案,但这是我不确定的部分: …声明变量volatile会使每次访问都变得不稳定。 不可能以任何其他方式强制执行此行为,因此不能用Interlocked替换volatile。 在其他库,接口或硬件可以访问您的变量并随时更新它或需要最新版本的情况下,这是必需的。 Interlocked是否保证对所有线程的primefaces操作的可见性,或者我是否仍然必须在值上使用volatile关键字以保证对更改的可见性? 这是我的例子: volatile int value = 100000; // 0) { // do something } } public void AThreadMethod() { while(value > 0) { // do something } } 更新: 我是一个糟糕的运动,我改变了原来的例子,所以这里又是: public class CountDownLatch { private volatile int m_remain; // <— do I need the volatile keyword here? private EventWaitHandle m_event; public […]

可以通过多个线程访问List 吗?

我打算在多个线程之间共享一个List。 该列表将在更改期间锁定,这种更改很少发生。 如果同时通过列表从不同的线程进行多次迭代,是否存在线程安全问题?

线程中止离开僵尸事务并破坏SqlConnection

我觉得这种行为不应该发生。 这是场景: 启动一个长期运行的SQL事务。 运行sql命令的线程被中止(不是我们的代码!) 当线程返回托管代码时,SqlConnection的状态为“已关闭” – 但该事务仍在sql server上打开。 SQLConnection可以重新打开,你可以尝试在事务上调用回滚,但它没有效果(不是我期望这种行为。重点是没有办法访问数据库上的事务并滚动它背部。) 问题只是在线程中止时没有正确清理事务。 这是.Net 1.1,2.0和2.0 SP1的问题。 我们正在运行.Net 3.5 SP1。 这是一个说明问题的示例程序。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SqlClient; using System.Threading; namespace ConsoleApplication1 { class Run { static Thread transactionThread; public class ConnectionHolder : IDisposable { public void Dispose() { } public void executeLongTransaction() { Console.WriteLine(“Starting a […]

连续检查队列

我想要一个函数在一个线程上连续检查队列是否有新的添加 显然,可以选择连续循环播放睡眠,但我希望减少浪费。 我考虑了某种类型的等待句柄,然后让队列发出信号,但我不能安全地重写Enqueue,因为它不是虚拟的。 现在我正在考虑封装一个Queue作为我的最佳选择,但是如果有更好的选择,我想问你们好人! 我的想法是:我希望许multithreading访问套接字连接,同时保证他们只读取其消息的响应,所以我将有一个线程调度和读取响应,然后用响应数据执行回调(以纯文本格式)

设计线程安全类

阅读MSDN文档时,它总是让您知道类是否是线程安全的。 我的问题是你如何设计一个线程安全的类? 我不是在谈论用锁定调用类我意味着我正在为Microsoft创建XXX class \ object而我想说它是“线程安全”我需要做什么?

C#中静态初始化程序的线程安全性

每个人都说静态初始化程序是线程安全的,但我担心一个特定的细节。 比方说我有 static class MyStaticClass { public static readonly object myField = MyOtherClass.GetNewObject(); } static class MyOtherClass { public static object GetNewObject() { /* arbitrary code that returns a new object */ } } 当MyStaticClass.myField尚未初始化时,C#保证以下哪一项? 如果线程1和2尝试一起访问myField ( GetNewObject顺序),则在线程2读取myField之前, GetNewObject将开始执行。 如果线程1和2尝试一起访问myField ( GetNewObject顺序),则在线程2读取myField之前, GetNewObject将完成执行。 一般来说CLR怎么样:如果它的保证与C#不同,它们在哪些方面有所不同? 在更新版本的.NET框架中是否更改了行为? 注意: 这是一个棘手的问题,我认为完整的答案可能会提到静态构造函数和静态初始化程序之间的区别,以及它们如何与beforefieldinit交互以产生声明的结果。

Thread.IsAlive和Thread.ThreadState == ThreadState.Running

我用if(Thread.IsAlive)来检查线程的状态。 表单正在此线程中运行。 有时在执行期间,即使表单保持打开状态,对Thread.IsAlive的调用似乎也在评估为false。 我想用if(Thread.ThreadState==ThreadState.Running)执行相同的检查。 这是正确的方法吗? 如果没有,可能的工作是什么?