gpt4 book ai didi

c# - 所有线程一次只能使用一种方法?

转载 作者:太空狗 更新时间:2023-10-29 21:50:56 24 4
gpt4 key购买 nike

我有几个对象继承自 ClassA,它有一个抽象方法 MethodA。

这些继承对象中的每一个都可以允许最多特定数量的线程同时进入它们的 MethodA。

问题:线程只能在一个对象的 MethodA 中,而不会同时处理其他对象的 MethodA。

我该如何解决这个问题?我正在考虑使用信号量,但不知 Prop 体该怎么做,因为我无法全神贯注地解决问题以找到解决方案。

编辑:

示例代码(可能包含语法错误:)

public class ClassA
{
public virtual void MethodA{}
}

public class OneOfMySubclassesOfClassA // there can be multiple instances of each subclass!
{
public override void MethodA{

// WHILE any number of threads are in here, THIS MethodA shall be the ONLY MethodA in the entire program to contain threads
EDIT2: // I mean: ...ONLY MethodA of a subclass (not of a instance of a subclass) in the entire program...
}
}

...and more subclasses...

最佳答案

派生类型与静态信号量一起用作基类中的类型参数,以在每个子类的所有实例之间共享一个信号量。然后有一些困惑以确保只有一种类型是事件的。快速测试表明这可以正常工作,但存在问题。

假设 ClassA1 的方法当前正在执行。如果执行此方法的新请求以高频率到达,则可能会发生其他派生类没有机会执行的情况,因为不断有新线程执行类 ClassA1 的方法。

internal abstract class ClassA<TDerived> : ClassA
{
private const Int32 MaximumNumberConcurrentThreads = 3;

private static readonly Semaphore semaphore = new Semaphore(ClassA<TDerived>.MaximumNumberConcurrentThreads, ClassA<TDerived>.MaximumNumberConcurrentThreads);

internal void MethodA()
{
lock (ClassA.setCurrentlyExcutingTypeLock)
{
while (!((ClassA.currentlyExcutingType == null) || (ClassA.currentlyExcutingType == typeof(TDerived))))
{
Monitor.Wait(ClassA.setCurrentlyExcutingTypeLock);
}

if (ClassA.currentlyExcutingType == null)
{
ClassA.currentlyExcutingType = typeof(TDerived);
}

ClassA.numberCurrentlyPossiblyExecutingThreads++;

Monitor.PulseAll(ClassA.setCurrentlyExcutingTypeLock);
}

try
{
ClassA<TDerived>.semaphore.WaitOne();

this.MethodACore();
}
finally
{
ClassA<TDerived>.semaphore.Release();
}

lock (ClassA.setCurrentlyExcutingTypeLock)
{
ClassA.numberCurrentlyPossiblyExecutingThreads--;

if (ClassA.numberCurrentlyPossiblyExecutingThreads == 0)
{
ClassA.currentlyExcutingType = null;

Monitor.Pulse(ClassA.setCurrentlyExcutingTypeLock);
}
}
}

protected abstract void MethodACore();
}

请注意,包装器方法用于调用 MethodACore 中的实际实现。所有派生类之间共享的所有同步对象都在一个非泛型基类中。

internal abstract class ClassA
{
protected static Type currentlyExcutingType = null;

protected static readonly Object setCurrentlyExcutingTypeLock = new Object();

protected static Int32 numberCurrentlyPossiblyExecutingThreads = 0;
}

派生类将如下所示。

internal sealed class ClassA1 : ClassA<ClassA1>
{
protected override void MethodACore()
{
// Do work here.
}
}

internal sealed class ClassA2 : ClassA<ClassA2>
{
protected override void MethodACore()
{
// Do work here.
}
}

很遗憾,我现在没有时间更详细地解释它是如何以及为什么起作用的,但我明天会更新答案。

关于c# - 所有线程一次只能使用一种方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14280504/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com