首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

多线程这么访问List对吗

2013-03-27 
多线程这样访问List对吗?多线程这样访问List。大家帮忙看一下DoWork这个函数这样访问List会不会有问题?publ

多线程这样访问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); 
   }
 }

热点排行