C# 如何允许所有子Qent线程通过;“大门”;

C# 如何允许所有子Qent线程通过;“大门”;,c#,concurrency,C#,Concurrency,我需要能够让多个线程等待一个信号量,但当我释放它们时,其他线程不应该再次等待该信号量——它应该只允许任何后续线程。我找不到这样的例子 这里有一个例子。设置“Result”属性后,我需要允许对其进行所有读取(而不仅仅是允许一次读取) 私有类TaskResultRapper { 私人T结果; 私有信号量lim valueSetSemaphore=新信号量lim(0,1); 私有取消令牌取消令牌; 公共任务结果说话者(CancellationToken CancellationToken) { thi

我需要能够让多个线程等待一个信号量,但当我释放它们时,其他线程不应该再次等待该信号量——它应该只允许任何后续线程。我找不到这样的例子

这里有一个例子。设置“Result”属性后,我需要允许对其进行所有读取(而不仅仅是允许一次读取)

私有类TaskResultRapper
{
私人T结果;
私有信号量lim valueSetSemaphore=新信号量lim(0,1);
私有取消令牌取消令牌;
公共任务结果说话者(CancellationToken CancellationToken)
{
this.cancellationToken=cancellationToken;
}
公众对结果的怀疑
{
得到{
valueSetSemaphore.Wait(cancellationToken);
返回结果;
}
设置
{
结果=值;
valueSetSemaphore.Release();
}
}
}

听起来你在用你的
TaskResultRapper
重新发明轮子。 看起来你真的可以用a来做这件事

请注意,这也支持取消。下面是一个例子:

using System;
using System.Threading.Tasks;

namespace ConsoleApp10
{
    class Program
    {
        static void Main()
        {
            var test = new TaskCompletionSource<int>();

            Task.Run(() => Parallel.Invoke(
                () => printValue(test.Task),
                () => printValue(test.Task),
                () => printValue(test.Task)));

            Console.WriteLine("Tasks are all waiting on the value; press return to continue.");
            Console.ReadLine();

            test.SetResult(42); // Or test.SetCanceled() to cancel it.

            Console.WriteLine("Set result to 42 (or cancelled)");
            Console.ReadLine();
        }

        static void printValue(Task<int> task)
        {
            try
            {
                Console.WriteLine(task.Result);
            }

            catch (Exception exception)
            {
                Console.WriteLine("Task received exception: " + exception.InnerException.Message);
            }
        }
    }
}
使用系统;
使用System.Threading.Tasks;
名称空间控制台10
{
班级计划
{
静态void Main()
{
var test=new TaskCompletionSource();
Task.Run(()=>Parallel.Invoke(
()=>printValue(test.Task),
()=>printValue(test.Task),
()=>printValue(test.Task));
WriteLine(“任务都在等待该值;按return继续。”);
Console.ReadLine();
test.SetResult(42);//或test.setcancelled()来取消它。
控制台写入线(“将结果设置为42(或取消)”;
Console.ReadLine();
}
静态无效打印值(任务)
{
尝试
{
Console.WriteLine(task.Result);
}
捕获(异常)
{
Console.WriteLine(“任务收到异常:+exception.InnerException.Message”);
}
}
}
}

尝试按原样运行,然后在将
test.SetResult(42)
更改为
test.SetCanceled()

这听起来像是在用
TaskResultRapper重新发明轮子。
看起来你真的可以用a来做这件事

请注意,这也支持取消。下面是一个例子:

using System;
using System.Threading.Tasks;

namespace ConsoleApp10
{
    class Program
    {
        static void Main()
        {
            var test = new TaskCompletionSource<int>();

            Task.Run(() => Parallel.Invoke(
                () => printValue(test.Task),
                () => printValue(test.Task),
                () => printValue(test.Task)));

            Console.WriteLine("Tasks are all waiting on the value; press return to continue.");
            Console.ReadLine();

            test.SetResult(42); // Or test.SetCanceled() to cancel it.

            Console.WriteLine("Set result to 42 (or cancelled)");
            Console.ReadLine();
        }

        static void printValue(Task<int> task)
        {
            try
            {
                Console.WriteLine(task.Result);
            }

            catch (Exception exception)
            {
                Console.WriteLine("Task received exception: " + exception.InnerException.Message);
            }
        }
    }
}
使用系统;
使用System.Threading.Tasks;
名称空间控制台10
{
班级计划
{
静态void Main()
{
var test=new TaskCompletionSource();
Task.Run(()=>Parallel.Invoke(
()=>printValue(test.Task),
()=>printValue(test.Task),
()=>printValue(test.Task));
WriteLine(“任务都在等待该值;按return继续。”);
Console.ReadLine();
test.SetResult(42);//或test.setcancelled()来取消它。
控制台写入线(“将结果设置为42(或取消)”;
Console.ReadLine();
}
静态无效打印值(任务)
{
尝试
{
Console.WriteLine(task.Result);
}
捕获(异常)
{
Console.WriteLine(“任务收到异常:+exception.InnerException.Message”);
}
}
}
}
试着按原样运行,然后将
test.SetResult(42)
更改为
test.SetCanceled()

我建议您使用。它就是为此而设计的。 在手动重置事件实例上调用WaitOne()的所有线程都将被阻止,直到调用Set()发出手动重置事件的信号。然后,所有被阻止的线程都被释放。

我建议您使用。它就是为此而设计的。
在手动重置事件实例上调用WaitOne()的所有线程都将被阻止,直到调用Set()发出手动重置事件的信号。然后,所有被阻止的线程都被释放。

您能告诉我们为什么需要此解决方案吗?潜在的业务问题是什么?实际上,我认为您最好使用
TaskCompletionSource
(根据我的回答),而不是编写自己的类并使用
ManualResetEvent
,但这可能取决于您的用例。您能告诉我们为什么需要此解决方案吗?潜在的业务问题是什么?实际上,我认为您最好使用
TaskCompletionSource
(根据我的回答),而不是编写自己的类并使用
ManualResetEvent
,但这可能取决于您的用例。在我的例子中,Ii必须使用支持统一取消(取消令牌)的在我的例子中,我不得不使用支持统一取消(取消令牌)的方法。对于这个例子,你完全正确。谢谢你的解决方案。对于这个案例,你是完全正确的。感谢您提供此解决方案。