问题描述
需求是这样的,批量发送邮件:选一批接收人,点击发送邮件,把这批人加到代发数组里(array),开启线程开始发送,发一封从array里remove掉一个,如果此时代发还没发完,这时又选一批接收人,点击发送邮件,要把这次选的人加到刚才的代发数组里继续发送代码如下:privatevoidbtnSend_click(){lock(arryList.SyncRoot){foreach(stringstrGroupinOneLstGroup.Items){poLedInfo[]pos=m_boLedInfo.GetInfoByGroupName(strGroup);foreach(poLedInfopoinpos){//SendToSingleMemeber(po,/*po.Name+":"+*/strContent);arryList.Add(newListItem(strContent,po));}}}if(!m_bSending)//开启线程发送{Threadt=newThread(newThreadStart(SendFunc));t.Start();}}//发送线程privatevoidSendFunc(){m_bSending=true;//正在发送lock(arryList.SyncRoot){while(arryList.Count>0){Console.WriteLine("----------------{0}",arryList.Count);ListItemlst=(ListItem)arryList[0];poLedInfopo=lst.ValueaspoLedInfo;SendToSingleMemeber(po,lst.Name);arryList.RemoveAt(0);Thread.Sleep(10);}}Console.WriteLine("''''''----------------{0}",arryList.Count);m_bSending=false;}
现在遇到问题了,第一次点button后进线程发送,第二次再点(第一次线程还没发完),程序就挂了,貌似死锁了估计是锁用的不对,哪位大神帮忙看下怎么改?谢谢
解决方案
解决方案二:
楼主你的号是从别人手里买来的吗?
解决方案三:
arryList.SyncRoot这个是静态吧?为什么不在当前类定义个变量呢?
解决方案四:
引用楼主gxingmin的回复:
需求是这样的,批量发送邮件:选一批接收人,点击发送邮件,把这批人加到代发数组里(array),开启线程开始发送,发一封从array里remove掉一个,如果此时代发还没发完,这时又选一批接收人,点击发送邮件,要把这次选的人加到刚才的代发数组里继续发送代码如下:privatevoidbtnSend_click(){lock(arryList.SyncRoot){foreach(stringstrGroupinOneLstGroup.Items){poLedInfo[]pos=m_boLedInfo.GetInfoByGroupName(strGroup);foreach(poLedInfopoinpos){//SendToSingleMemeber(po,/*po.Name+":"+*/strContent);arryList.Add(newListItem(strContent,po));}}}if(!m_bSending)//开启线程发送{Threadt=newThread(newThreadStart(SendFunc));t.Start();}}//发送线程privatevoidSendFunc(){m_bSending=true;//正在发送lock(arryList.SyncRoot){while(arryList.Count>0){Console.WriteLine("----------------{0}",arryList.Count);ListItemlst=(ListItem)arryList[0];poLedInfopo=lst.ValueaspoLedInfo;SendToSingleMemeber(po,lst.Name);arryList.RemoveAt(0);Thread.Sleep(10);}}Console.WriteLine("''''''----------------{0}",arryList.Count);m_bSending=false;}现在遇到问题了,第一次点button后进线程发送,第二次再点(第一次线程还没发完),程序就挂了,貌似死锁了估计是锁用的不对,哪位大神帮忙看下怎么改?谢谢
为何解析的时候要不停的起新的线程呢?消费者线程起一个就够了。个人理解:运行时间段-线程池,时间长-单独线程。
解决方案五:
用Queue<ListItem>代替Array就不用锁了。
解决方案六:
你这么写,只有第一次点击的所有邮件发送完,才能添加本次新增的列表
解决方案七:
http://blog.csdn.net/wangzhiyu1980/article/details/45497907
解决方案八:
去掉锁,用公共变量m_bSending控制,每次点击按钮,先停止邮件发送,添加新邮件到列表后,再开始发送邮件publicboolisFinished=false;//当前发送的邮件完成是否完成privatevoidbtnSend_click(){//lock(arryList.SyncRoot)//{m_bSending=false;//计划停止发送while(!isFinished){System.Threading.Thread.Sleep(30000);//给足够时间让当前发送邮件完成}//假设你下面的代码是在添加新邮件到列表foreach(stringstrGroupinOneLstGroup.Items){poLedInfo[]pos=m_boLedInfo.GetInfoByGroupName(strGroup);foreach(poLedInfopoinpos){//SendToSingleMemeber(po,/*po.Name+":"+*/strContent);arryList.Add(newListItem(strContent,po));}}//}if(!m_bSending)//开启线程发送{Threadt=newThread(newThreadStart(SendFunc));t.Start();}}//发送线程privatevoidSendFunc(){m_bSending=true;//正在发送//lock(arryList.SyncRoot)//{while(arryList.Count>0&&m_bSending){isFinished=false;Console.WriteLine("----------------{0}",arryList.Count);ListItemlst=(ListItem)arryList[0];poLedInfopo=lst.ValueaspoLedInfo;SendToSingleMemeber(po,lst.Name);arryList.RemoveAt(0);Thread.Sleep(10);isFinished=true;}//}Console.WriteLine("''''''----------------{0}",arryList.Count);m_bSending=false;}
解决方案九:
4楼的做法可以