- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在开发一个 WCF 应用程序,该应用程序托管一个自定义对象供许多客户端访问。它基本上可以工作,但因为我需要处理数以千计的并发客户端,所以我需要该服务能够处理并发读取调用(更新频率不高)。我通过在更新对象时锁定私有(private)字段来添加一些线程安全。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public sealed class TestServerConfig : ConfigBase, ITestInterface
{
private object updateLock = new object();
private SortedList<string, DateTime> dates = new SortedList<string, DateTime>();
public DateTime GetDate(string key)
{
if (this.dates.ContainsKey(key))
{
return this.dates[key];
}
else
{
return DateTime.MinValue;
}
}
public void SetDate(string key, DateTime expirationDate)
{
lock (this.updateLock)
{
if (this.dates.ContainsKey(key))
{
this.dates[key] = expirationDate;
}
else
{
this.dates.Add(key, expirationDate);
}
}
}
}
我的问题是如何在不锁定的情况下使 GetDate 线程安全,以便可以执行对 GetDate 的并发调用,但在检查之后但读取值之前从集合中删除值时,不会随机发生异常。
捕获异常并处理它是可能的,但我更愿意保留它。
有什么想法吗?
最佳答案
有专门为此设计的锁,ReaderWriterLockSlim (ReadWriterLock 如果您使用的是低于 .NET 4.0 的版本)
此锁允许并发读取,但会在发生写入时锁定读取(和其他写入)。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public sealed class TestServerConfig : ConfigBase, ITestInterface
{
private ReaderWriterLockSlim updateLock = new ReaderWriterLockSlim();
private SortedList<string, DateTime> dates = new SortedList<string, DateTime>();
public DateTime GetDate(string key)
{
try
{
this.updateLock.EnterReadLock();
if (this.dates.ContainsKey(key))
{
return this.dates[key];
}
else
{
return DateTime.MinValue;
}
}
finally
{
this.updateLock.ExitReadLock();
}
}
public void SetDate(string key, DateTime expirationDate)
{
try
{
this.updateLock.EnterWriteLock();
if (this.dates.ContainsKey(key))
{
this.dates[key] = expirationDate;
}
else
{
this.dates.Add(key, expirationDate);
}
}
finally
{
this.updateLock.ExitWriteLock();
}
}
}
还有支持超时的锁的“尝试”版本,您只需检查返回的 bool 值,看看您是否拿走了锁。
更新:另一种解决方案是使用 ConcurrentDictionary ,这根本不需要任何锁。 ConcurrentDictionary 在内部使用锁,但它们的生命周期比您可以使用的锁的生命周期短,而且 Microsoft 也有可能使用某种形式的不安全方法来进一步优化它,我不知道他们在内部采用哪种锁。
不过你需要做一些重写以使你的操作原子化
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public sealed class TestServerConfig : ConfigBase, ITestInterface
{
private ConcurrentDictionary<string, DateTime> dates = new ConcurrentDictionary<string, DateTime>();
public DateTime GetDate(string key)
{
DateTime result;
if (this.dates.TryGetValue(key, out result))
{
return result;
}
else
{
return DateTime.MinValue;
}
}
public void SetDate(string key, DateTime expirationDate)
{
this.dates.AddOrUpdate(key, expirationDate, (usedKey, oldValue) => expirationDate);
}
}
更新 2: 出于好奇,我深入了解 ConcurrentDictionary
做了什么,它所做的只是锁定元素的一组桶,所以如果两个对象也共享相同的哈希桶锁,您只会发生锁争用。
通常有 Environment.ProcessorCount * 4
锁桶,但您可以使用设置 concurrencyLevel 的构造函数手动设置它.
这是它如何决定使用哪个锁
private void GetBucketAndLockNo(int hashcode, out int bucketNo, out int lockNo, int bucketCount, int lockCount)
{
bucketNo = (hashcode & 2147483647) % bucketCount;
lockNo = bucketNo % lockCount;
}
lockCount
等于构造函数中设置的 concurrencyLevel
。
关于c# - 服务中的线程安全设置为 ConcurrencyMode.Multiple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17432623/
我已开始使用WCF来开发WINDOWS服务托管的calc引擎的第一步。该服务运行良好,但似乎所有调用都只使用一个线程,但我需要它具有可伸缩性并使用多线程。 忽略代码等中的所有跟踪信息,因为这是该应用程
我有一个具有以下设置的WCF服务: NetNamedPipeBinding ConcurrencyMode。多个 InstanceContextMode.Single 现在,我有一个以多线程方式访问此
我阅读了很多关于 wcf 并发和实例上下文模式的文章,我也阅读了有关它的 CodeProject 文章,但仍然无法让它工作。 这是我的客户端代码(如果你问我为什么要使用实例上下文,那是因为我最终会测试
我正在开发一个 WCF 应用程序,该应用程序托管一个自定义对象供许多客户端访问。它基本上可以工作,但因为我需要处理数以千计的并发客户端,所以我需要该服务能够处理并发读取调用(更新频率不高)。我通过在更
我想了解 ServiceBehavior.ConcurrencyMode 属性。 在服务端考虑以下代码: [ServiceContract] public interface IMySercice {
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 3 年前。 Improve this ques
有一个处理传入请求的 WCF 服务,并且为每个传入消息生成一个相应的输出消息,该消息被发送到另一个 WCF 服务。消息的顺序很重要,不能打乱。因此,服务应按照服务接收消息的顺序生成相应的输出消息。同时
EF 默认为无并发控制(最后一次写入获胜),这允许丢失更新。 可以通过在 RowVersion 列上设置 ConcurrencyMode=Fixed 来明确配置强制开放式并发检查。 我们如何在所有表的
我是 WCF 新手。我有一个 WCF,其中有许多应用程序使用此服务。而我的要求是,WCF 服务应该同时处理多个请求。我知道这可以通过使用 [ServiceBehavior(ConcurrencyMod
我有一个带有 ConcurrencyMode = ConcurrencyMode.Multiple 选项的 WCF 服务。考虑到服务请求是并发处理的事实,我可以安全地读取传入请求 HTTP heade
我的 wcf 服务配置有问题。我希望每次调用我的服务时都创建一个新的服务实例。对于并发性,我希望一个调用在另一个调用开始之前完成。 因此,如果我有这样的服务: [ServiceBehavior(Con
我是否需要在使用 ConcurrencyMode.Multiple 的 WCF 服务中实现自己的锁定?和 InstanceContextMode.PerCall或 InstanceContextMod
我查看了不同的 WCF 服务行为( ConcurrencyModes/InstanceContextModes ),但没有得到 ConcurrencyMode 之间的区别“单个”/“多个”使用 Ins
客户端通过单个 WCF channel 从单个线程向服务器发送大量消息。 客户端使用 BeginMyMethod(x, b) 发送消息,因为它不希望在处理消息时阻塞。 我们开启了可靠的消息传递,因为我
我们模型中的大多数表都有一个名为“intConcurrencyID”的字段,我们打算将其用于并发检查。我相信在 Database First 环境中启用此字段以进行并发检查的唯一方法是将并发模式设置为
我有一个具有 ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = Concurren
我有一个定义为 ConcurrencyMode.Single 的服务: [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, U
我们有一个 WCF 服务,可以进行大量事务性 NHibernate 调用。有时我们会看到 SQL 超时,即使调用正在更新不同的行并且表被设置为行级锁定。 在深入研究日志后,看起来不同的线程正在进入代码
我有一个带有静态数据上下文的 WCF 服务,但没有并发性。它已经运行了一年,没有任何问题,但前几天我们看到了一些奇怪的行为,用户正确地传递了数据,但得到了意想不到的不正确的数据。这确实通过了 F5,所
我是一名优秀的程序员,十分优秀!