首页 新闻 搜索 专区 学院

关于多线程异常[从不同步的代码块中调用了对象同步方法。]求解决方法,完整代码如下

0
悬赏园豆:50 [待解决问题]

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;
}
}

Brids的主页 Brids | 初学一级 | 园豆:10
提问于:2013-06-12 13:41
< >
分享
所有回答(3)
0

Monitor.Enter在这个场景下用不对吧,Monitor范围太宽,系统死锁等问题不好处理

2012 | 园豆:19163 (专家六级) | 2013-06-12 16:02

那应该怎么处理呢 ?

支持(0) 反对(0) Brids | 园豆:10 (初学一级) | 2013-06-12 16:12
0

Monitor是线程关联的对象。。。所以你再A线程调用了Enter。必须在A线程进行Exit。。。你代码中调用委托的BeginInvoke实际上又开启了一个新的线程,也就是说你再A线程调用了Enter却在B线程调用了Exit。。。所以你就报错了。

 

更多关于异步编程的资料请看:那些年,我们一起追寻的异步编程[系列]

滴答的雨 | 园豆:3690 (老鸟四级) | 2013-06-12 17:13
0

用Semaphore 或 SemaphoreSlim 吧。

天方 | 园豆:5266 (大侠五级) | 2013-06-12 21:43
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册