读书人

多线程这么访问List对吗

发布时间: 2013-03-27 11:22:42 作者: rapoo

多线程这样访问List对吗?
多线程这样访问List。

大家帮忙看一下DoWork这个函数这样访问List会不会有问题?



public partial class Form1 : Form
{
int count = 8;
object obj = new object();
Thread thread;
ManualResetEvent[] events;
List<TaskInfo> tasks;
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
txtMsg.Text = "";
thread = new Thread(new ThreadStart(Test));
thread.Start();

}

public void Test()
{
events = new ManualResetEvent[count];
tasks = Init();
for (int i = 0; i < count; i++)
{
events[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), i);
}

ManualResetEvent.WaitAll(events);

InvokeSetText("任务完成");
}

public void DoWork(object o)
{
int i = (int)o;
TaskInfo model;
while (tasks.Count > 0)
{
Monitor.Enter(obj);
try
{
model = tasks[0];
tasks.RemoveAt(0);
}


finally
{
Monitor.Exit(obj);
}
Thread.Sleep(2000);
//长任务抓网页Snap(model.Url);
InvokeSetText(string.Format("{0} 线程:{1}",model.Name,o));
Thread.Sleep(1000);
}
events[i].Set();
}

public delegate void SetTextHandler(string msg);

public void InvokeSetText(string msg)
{
SetTextHandler d = new SetTextHandler(SetText);
Invoke(d, msg);
}

public void SetText(string msg)
{
txtMsg.Text = msg + "\r\n" + txtMsg.Text;
}


public List<TaskInfo> Init()
{
List<TaskInfo> taskInfos = new List<TaskInfo>();
TaskInfo task;
for (int i = 0; i < 30; i++)
{
task = new TaskInfo(i.ToString(), string.Format("任务{0}", i),"www.hao123.com");
taskInfos.Add(task);
}

return taskInfos;

}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (thread != null)
{
thread.Abort();

}


}
}

public class TaskInfo
{
private string m_Id;
private string m_Name;
private string m_Url;

public string Id
{
get { return m_Id; }
set { m_Id = value; }
}


public string Name
{
get { return m_Name; }
set { m_Name = value; }
}

public string Url
{
get { return m_Url; }
set { m_Url = value; }
}

public TaskInfo()
{ }

public TaskInfo(string _id, string _name,string _url)
{
m_Id = _id;
m_Name = _name;
m_Url = _url;
}

}


[解决办法]
貌似可以,简单点写法也可以这样

lock(obj)
{
model = tasks[0];
tasks.RemoveAt(0);
}
[解决办法]
先不说有没有问题,
在你当前的需求下
List<TaskInfo> tasks; 这个结构不如先改成
Queue<TaskInfo> tasks;
这样有利于你以后扩展
[解决办法]
引用:
这个例子就是用来测试的,但是测试了很久都没发现什么问题 。

就是担心会不会出现,像 @qldsrx 同志说的问题??


那么你可以在Monitor.Enter之后再次判断,例如
lock(obj)
{
if(task.count==0)
break;
else
{
model = tasks[0];
tasks.RemoveAt(0);
}
}

读书人网 >C#

热点推荐