Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建FIFO/强信号量_C#_.net_Multithreading_Concurrency - Fatal编程技术网

C# 如何创建FIFO/强信号量

C# 如何创建FIFO/强信号量,c#,.net,multithreading,concurrency,C#,.net,Multithreading,Concurrency,我需要用C#编写自己的FIFO/强信号量,使用自己的信号量类作为基础。我找到了,但它不太正确,因为我还不应该使用Monitor.Enter/Exit 这些是我的常规信号量的方法,我想知道是否有一种简单的方法将其调整为FIFO public virtual void Acquire() { lock (this) { while (uintTokens == 0) { Monitor.Wait(this);

我需要用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);

    }

}

因此,
SemaphoreSlim
为我们提供了一个良好的起点,因此我们将首先在一个新类中包装其中一个,并将除wait方法之外的所有内容定向到该信号量

为了获得类似队列的行为,我们需要一个队列对象,并且为了确保它在面对多线程访问时是安全的,我们将使用
ConcurrentQueue

在这个队列中,我们将放置
TaskCompletionSource
对象。当我们想让某个项目开始等待时,它可以创建一个TCS,将其添加到队列中,然后通知信号量异步弹出队列中的下一个项目,并在等待完成时将其标记为“已完成”。我们将知道,当队列中有项目时,将始终有相等或更少数量的延续

然后我们只需等待来自TCS的
任务

我们还可以创建一个
WaitAsync
方法来返回任务,只需返回它而不是等待它

public class SemaphoreQueue
{
    private SemaphoreSlim semaphore;
    private ConcurrentQueue<TaskCompletionSource<bool>> queue =
        new ConcurrentQueue<TaskCompletionSource<bool>>();
    public SemaphoreQueue(int initialCount)
    {
        semaphore = new SemaphoreSlim(initialCount);
    }
    public SemaphoreQueue(int initialCount, int maxCount)
    {
        semaphore = new SemaphoreSlim(initialCount, maxCount);
    }
    public void Wait()
    {
        WaitAsync().Wait();
    }
    public Task WaitAsync()
    {
        var tcs = new TaskCompletionSource<bool>();
        queue.Enqueue(tcs);
        semaphore.WaitAsync().ContinueWith(t =>
        {
            TaskCompletionSource<bool> popped;
            if (queue.TryDequeue(out popped))
                popped.SetResult(true);
        });
        return tcs.Task;
    }
    public void Release()
    {
        semaphore.Release();
    }
}
公共类信号量
{
私有信号量lim信号量;
私有并发队列=
新的ConcurrentQueue();
公共信号量相等(int initialCount)
{
信号量=新信号量lim(initialCount);
}
公共信号量相等(int initialCount,int maxCount)
{
信号量=新信号量lim(initialCount,maxCount);
}
公共无效等待()
{
WaitAsync().Wait();
}
公共任务WaitAsync()
{
var tcs=new TaskCompletionSource();
排队;排队(tcs);
semaphore.WaitAsync().ContinueWith(t=>
{
TaskCompletionSource弹出;
if(queue.TryDequeue(弹出))
popped.SetResult(true);
});
返回tcs.Task;
}
公开无效释放()
{
semaphore.Release();
}
}

我已经创建了一个FifosMaphore类,并且正在我的解决方案中成功地使用它。当前的限制是,它的行为类似于信号量(1,1)

在每个线程上:

fifoSemaphore.WaitOne();
//do work
fifoSemaphore.Release();

与您的问题不太相关,但您可能希望避免使用
lock(this)
code模式,因为它可能导致死锁。你一定是在用信号灯吗?您打算使用ConcurrentQueue作为基础吗?老师希望我们自己制作所有的实用程序,所以我们不使用任何内置的并发工具。不过我有自己的频道课。谢谢你的提示LB2,老师对它没有问题,但我还是会去修改它的。我检查了的源代码,看起来它已经是FIFO了。为等待创建的每个任务都存储在一个以双链表形式实现的队列中。可以找到一个FIFO
信号量LIM
的基本实现,它具有一个
public void-right(int-amount)
方法作为额外功能。其中有很多东西我们没有学过,这意味着我们并不打算使用它们。例如,等等。另外,我有自己的通道类(线程安全队列),我想可以使用它。@FreddieAppsHero欢迎您使用自己的工具使用相同的模型,如果您愿意的话。我自己的信号量缺少WaitAsync,可能不赞成再扩展它。@FreddieAppsHero这当然是您的决定。
FifoSemaphore fifoSemaphore = new FifoSemaphore();
fifoSemaphore.WaitOne();
//do work
fifoSemaphore.Release();