我需要创建一个使用两个线程计数到10的程序
一个线程应该打印偶数,另一个应该打印奇数
这些线程应按顺序打印数字(1,2,3,4,5 ...)
我已经完成了这段代码,但似乎没有用......有什么想法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
private static AutoResetEvent autoEvent;
private static int num = 10;
static void DoWork(object data)
{
var counter = (int)data;
if (counter == 1)
{
autoEvent.WaitOne();
}
while (counter <= num)
{
Console.WriteLine(counter);
counter += 2;
autoEvent.Set();
autoEvent.WaitOne();
}
}
static void Main(string[] args)
{
autoEvent = new AutoResetEvent(false);
var evenCounter = new Thread(DoWork);
evenCounter.Start(0);
var notEvenCounter = new Thread(DoWork);
notEvenCounter.Start(1);
Console.ReadLine();
}
}
}
答案 0 :(得分:1)
该代码autoEvent.WaitOne()
可能无法阻止,因为AutoResetEvent
已处于信号状态:
autoEvent.Set();
autoEvent.WaitOne();
因此该线程不会按照您的计划等待另一个线程
要解决该问题,您需要使用2 AutoResetEvent
s。一个线程将在第一个AutoResetEvent
上等待,第二个线程将在第二个AutoResetEvent
上等待。每个帖子都会发出一个AutoResetEvent
的信号,表示该属于&#39;到另一个线程
为了证明我的想法,我只会向您展示需要进行更改的代码行:
private static AutoResetEvent autoEvents[] = new AutoResetEvent[2];
...
autoEvents[0] = new AutoResetEvent(false);
autoEvents[1] = new AutoResetEvent(false);
...
var counter = (int)data;
int initial_counter = counter;
...
if (counter == 1)
{
autoEvents[initial_counter].WaitOne();
}
...
autoEvents[1 - initial_counter].Set();
autoEvents[initial_counter].WaitOne();
在DoWork结束时发出相应的AutoResetEvent
以避免无限制阻塞另一个线程:
autoEvents[1 - initial_counter].Set();
答案 1 :(得分:0)
这似乎是你的问题:
autoEvent.Set();
autoEvent.WaitOne();
您可以设置锁定,然后立即等待锁定,这将导致任意执行模式。
我建议您使用2个锁,因此一个线程可以阻止另一个。
答案 2 :(得分:0)
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadTest
{
class Program
{
static void Main(string[] args)
{
Thread t1 = new Thread(Method1);
Thread t2 = new Thread(Method2);
t1.Start();
Thread.Sleep(100);
t2.Start();
t1.Join();
t2.Join();
_autoEvent1.Close();
_autoEvent2.Close();
}
private static void Method1()
{
do
{
_autoEvent2.WaitOne();
if (!SharedCode(Thread.CurrentThread.ManagedThreadId))
{
break;
}
_autoEvent1.Set();
} while (true);
}
private static void Method2()
{
do
{
_autoEvent1.WaitOne();
//_autoEvent2.Set();
if (!SharedCode(Thread.CurrentThread.ManagedThreadId))
break;
_autoEvent2.Set();
} while (true);
}
private static bool SharedCode(int threadId)
{
lock (_lockObject)
{
Interlocked.Increment(ref _count);
if (_count > 10)
return false;
Console.WriteLine("ThreadId={0} , count={1}", threadId,_count);
}
return true;
}
private static AutoResetEvent _autoEvent1 = new AutoResetEvent(true);
private static AutoResetEvent _autoEvent2 = new AutoResetEvent(true);
private static Object _lockObject = new object();
private static int _count = 0;
}
}