相关疑难解决方法(0)

锁(this)和静态对象上的锁之间的区别

以下哪两个代码段更适合使用?

static readonly object _locker = new object();
lock (_locker)
Run Code Online (Sandbox Code Playgroud)

要么

lock (this)
Run Code Online (Sandbox Code Playgroud)

this是当前实例的对象.那么为什么lock (_locker)总是在书中呢?

相关:
lock(this)和lock(thisLock)有什么区别?
为什么锁(这个){...}不好?

.net c# multithreading locking thread-safety

11
推荐指数
2
解决办法
1万
查看次数

这是正确使用互斥锁吗?

我有一种情况,我可能会同时运行一个程序的多个实例,并且重要的是只有一个特定的函数不能同时在多个这些实例中执行.

这是使用互斥锁来防止这种情况发生的正确方法吗?

lock (this.GetType()) {
    _log.Info("Doing Sync");
    DoSync();
    _log.Info("Sync Completed");
}
Run Code Online (Sandbox Code Playgroud)

c# mutex

10
推荐指数
2
解决办法
3235
查看次数

c#锁定问题:锁定(此)vs锁定(SyncRoot)

我有一个类型集合字段的类.

问题:

  1. 如果我lock(this),我是否也有效锁定了收藏?
  2. 什么更有效,做lock(this)或创建一个SyncRoot对象lock(SyncRoot)呢?

c# locking

9
推荐指数
2
解决办法
4774
查看次数

为什么锁定(objLock)比锁定(这个)更好?

可能重复:
为什么锁(这个){...}不好?


在C#中,通常使用lock(objLock),其中objLock是为了锁定而创建的对象.

为什么锁定(这个)更好?除了锁定类本身之外,锁(this)的负面含义是什么?

c# locking

8
推荐指数
1
解决办法
1377
查看次数

lock(this)和lock(thisLock)有什么区别?

我正在读锁定语句(C#参考),在那里我看到了这段代码:

class Account
{
    private Object thisLock = new Object();

    //...

    int Withdraw(int amount)
    {
        lock (thisLock)
        {
           //....
        }
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

我想知道如果我们写lock(this)而不是lock(thisLock)在上面的例子中会有什么不同.如果你的答案取决于它,请参阅完整的例子.

如果您认为lock(this)和之间确实存在一些差异lock(thisLock),那么请帮助我理解所有重点之间的差异.特别是,每个人究竟意味着什么?

c# multithreading locking

8
推荐指数
1
解决办法
1669
查看次数

关于SyncRoot模式的一些说明:使用此模式的正确方法是什么?

我读了一些关于SyncRoot模式的内容,作为避免死锁的一般规则.阅读几年前的问题(见此链接),我想我明白这种模式的一些用法可能是不正确的.特别是,我专注于本主题的以下句子:

您会注意到System.Collections中许多集合上的SyncRoot属性.在回顾中,我认为这个属性是一个错误......请放心,我们不会犯这个错误,因为我们构建这些集合的通用版本.

实际上,例如,List<T>类不实现SyncRoot属性,或者更正确地实现它是显式实现的(请参阅此答案),因此必须强制转换ICollection才能使用它.但是这篇评论认为,SyncRoot公开私人领域与锁定一样糟糕this(见这个答案),这也在本评论中得到证实.

因此,如果我理解正确,当我实现非线程安全的数据结构时,因为它可以在多线程上下文中使用,所以我不应该(实际上,我不能)提供该SyncRoot属性.但是我应该让开发人员(将使用此数据结构)的任务是将其与私有SyncRoot对象相关联,如下面的示例代码所示.

public class A
{
    private MyNonThreadSafeDataStructure list;
    private readonly object list_SyncRoot = new object;

    public Method1()
    {
        lock(list_SyncRoot)
        {
            // access to "list" private field
        }
    }

    public Method2()
    {
        lock(list_SyncRoot)
        {
            // access to "list" private field
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

总之,我了解同步/锁定的最佳实践应如下所示:

  1. 不应通过公共属性公开任何私有SyncRoot对象; 换句话说,自定义数据结构不应提供公共SyncRoot属性(另请参阅此注释).
  2. 通常,不必使用私有对象进行锁定(请参阅此答案 …

.net c# multithreading thread-safety

8
推荐指数
1
解决办法
3047
查看次数

具有固定大小FIFO队列的生产者/消费者模式

我需要在固定大小的FIFO队列周围实现生产者/消费者模式.我认为围绕ConcurrentQueue的包装类可能适用于此,但我不完全确定(我之前从未使用过ConcurrentQueue).这种扭曲是队列只需要保存固定数量的项目(在我的例子中是字符串).我的应用程序将有一个生产者任务/线程和一个消费者任务/线程.当我的消费者任务运行时,它需要在那个时刻出现队列中存在的所有项目并对其进行处理.

对于它的价值,我的消费者处理排队的项目只不过是通过SOAP将它们上传到一个不是100%可靠的网络应用程序.如果无法建立连接或调用SOAP调用失败,我应该丢弃这些项目并返回队列以获取更多信息.由于SOAP的开销,我试图最大化队列中可以在一次SOAP调用中发送的项目数.

有时,我的制作人可能会比我的消费者能够删除和处理它们更快地添加项目.如果队列已满并且我的生产者需要添加另一个项目,我需要将新项目排队,然后将最旧的项目出列,以便队列的大小保持固定.基本上,我需要始终保留队列中生成的最新项目(即使这意味着某些项目不会被消耗,因为我的消费者当前正在处理以前的项目).

关于生产者如果队列中的项目是固定的那样保留数字,我从这个问题中发现了一个潜在的想法:

固定大小队列,在新的enques上自动将旧值出列

我目前在ConcurrentQueue周围使用一个包装类(基于该答案)和Enqueue()方法,如下所示:

public class FixedSizeQueue<T>
{
    readonly ConcurrentQueue<T> queue = new ConcurrentQueue<T>();

    public int Size { get; private set; }

    public FixedSizeQueue(int size)
    {
        Size = size;
    }

    public void Enqueue(T obj)
    {
        // add item to the queue
        queue.Enqueue(obj);

        lock (this) // lock queue so that queue.Count is reliable
        {
            while (queue.Count > Size) // if queue count > max queue size, then dequeue an item
            {
                T objOut;
                queue.TryDequeue(out objOut);
            }
        } …
Run Code Online (Sandbox Code Playgroud)

.net c# queue producer-consumer concurrent-collections

6
推荐指数
2
解决办法
4188
查看次数

我可以使用字典元素作为锁定对象吗?

我有多个队列正在被多个线程访问.为了实现线程安全,我做了以下事情:

private static Dictionary<string, Queue<string>> MyQueues = new Dictionary<string, Queue<string>>();

public static string GetNextQueueElementForKey(string key)
{
    string res = string.Empty;

    if (MyQueues.Keys.Contains(key))
    { 
       Queue<string> queue = MyQueues[key];
       lock (queue)
       {
           if (queue.Count() > 0)
           {
               res = queue.Dequeue();
           }
       }
   }

   return res;
}
Run Code Online (Sandbox Code Playgroud)

我也可以锁定MyQueues,但是我会锁定不必要的东西.所以我的问题是,如果锁定字典中包含的对象将起作用 - 假设一个键的值(队列)永远不会改变.

c# multithreading locking

6
推荐指数
1
解决办法
2243
查看次数

C#中的锁定范围:返回的对象是否仍然"锁定"?

假设我有一个包含的对象A.

// ...

private List<double> someList = new List<double>();

// ... 

public List<double> SomeList
{
    get { lock (this) { return someList; } }
}

// ...
Run Code Online (Sandbox Code Playgroud)

在下面的代码中对列表执行操作是否是线程安全的.知道几个操作可以由不同的线程同时执行.

A.SomeList.Add(2.0);
Run Code Online (Sandbox Code Playgroud)

要么

A.SomeList.RemoveAt(0);
Run Code Online (Sandbox Code Playgroud)

换句话说,什么时候锁被释放?

c# multithreading thread-safety

5
推荐指数
2
解决办法
2086
查看次数

如何创建FIFO /强信号量

我需要在C#中编写自己的FIFO /强信号量,使用我自己的信号量类作为基础.我找到了这个例子,但它不是很正确,因为我不应该使用Monitor.Enter/Exit.

这些是我的常规信号量的方法,我想知道是否有一种简单的方法可以使它适应FIFO.

public virtual void Acquire()
{

    lock (this)
    {

        while (uintTokens == 0)
        {

            Monitor.Wait(this);

        }

        uintTokens--;

    }

}

public virtual void Release(uint tokens = 1)
{

    lock (this)
    {

        uintTokens += tokens;
        Monitor.PulseAll(this);

    }

}
Run Code Online (Sandbox Code Playgroud)

.net c# concurrency multithreading

5
推荐指数
1
解决办法
3511
查看次数