class Program
{
static void Main(string[] args)
{
string[] userArray = { "123", "456", "789" };
for (int i = 0; i < 3; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(DoJoinGroup));
t.Name = "线程" + (i + 1);
t.Start(new ThreadParameter(i + 1, userArray[i]));
}
}
private static void AsyncMonitorCallBack(IAsyncResult ar)
{
if (ar.IsCompleted)
{
Monitor.Exit(_lock);
}
}
private static void DoJoinGroup(object threadParameter)
{
ThreadParameter parameter = threadParameter as ThreadParameter;
int i = 0;
while (true)
{
Thread.Sleep(1000);
Monitor.Enter(_lock);
//JoinGroups可能为一个比较耗时的操作,所以不能使用Invoke方法
JoinGroupHandler handler = new JoinGroupHandler(JoinGroups);
handler.BeginInvoke(parameter.Number, AsyncMonitorCallBack, null);
}
}
private static void JoinGroups(string loginNumber)
{
Random rd = new Random();
int id = rd.Next(1, 1000000);
Console.WriteLine(Thread.CurrentThread.Name + " : " + "正在尝试添加组," + id.ToString());
}
private delegate void JoinGroupHandler(string loginNumber);
private static object _lock = new object();
}
public class ThreadParameter
{
public int ThreadIndex { get; set; }
public string Number { get; set; }
public ThreadParameter(int threadindex, string number)
{
this.ThreadIndex = threadindex;
this.Number = number;
}
}
Monitor.Enter在这个场景下用不对吧,Monitor范围太宽,系统死锁等问题不好处理
那应该怎么处理呢 ?
Monitor是线程关联的对象。。。所以你再A线程调用了Enter。必须在A线程进行Exit。。。你代码中调用委托的BeginInvoke实际上又开启了一个新的线程,也就是说你再A线程调用了Enter却在B线程调用了Exit。。。所以你就报错了。
更多关于异步编程的资料请看:那些年,我们一起追寻的异步编程[系列]
用Semaphore 或 SemaphoreSlim 吧。