我在下面有一个示例代码,它创建多线程,在单独的线程中lock
具有代码块。如果响应为空或autoReset.WaitOne(timeout)
超过时间跨度,我中止子线程,以便允许队列中的下一个等待线程进入lock
并进行操作。但这里的问题是,如果说 ThreadA 需要 8 秒才能在 lock
中执行复杂的代码,那么下一个等待线程说 ThreadB 只剩下 2 秒(因为所有线程的AutoResetEvent's
等待时间是同时启动的(。
如何使每个线程获得相同的时间跨度来执行复杂的代码块。我现在正在尝试从过去 2 天开始解决这个问题,任何输入都会非常有帮助。
Class A
{
static void Main(){
for(int i=0; i < 2; i++)
{
var mainThread = new Thread(ParentThreadMethod);
mainThread.Start();
}
}
void ParentThreadMethod(){
var autoReset = new AutoResetEvent(false);
ClassB obj;
var childThread = new Thread(() =>
{
obj = new ClassB();
var result = obj.ChildThreadMethod();
autoReset.Set();
}
childThread.Start();
// wait for 10sec
autoReset.WaitOne(10000);
}
}
Class B
{
private static readonly object threadLock = new object();
string ChildThreadMethod(){
lock (threadLock)
{
// complex logic taking 8sec
}
}
}
我认为问题是两个线程共享对
private static readonly object threadLock = new object();
这意味着第二个线程将花费 8 秒等待第一个线程退出关键区域。这使得它看起来像超时提前到来。但是超时工作正常。
看起来您只想在成功进入锁定时才开始超时。这意味着线程本身必须启动超时,因为只有子线程知道它何时进入锁。
它可能看起来像这样:
lock (threadLock) {
var timeoutTask = Task.Delay(10000);
var workTask = Task.Run(RunWork);
var firstTask = Task.WhenAny(timeoutTask, workTask).Result;
if (!workTask.IsCompleted) {
AbortWork();
workTask.Wait(); //Wait for cancellation to finish.
}
}
通常,较新的 TPL 功能比线程和事件等更容易使用。如果这段代码是新代码,我会从 TPL 类重新开始。