多线程和委托

//Task 取消线程

        CancellationTokenSource cts = new CancellationTokenSource();

            cts.Cancel();//传达取消请求

            if (cts.IsCancellationRequested)
            {
                MessageBox.Show(@"取消成功.");
            }
            else
            {
                MessageBox.Show(@"没有取消,还在执行.");
            }
            Task.Factory.StartNew(new Action(() =>
            {
                MessageBox .Show (@"这里是一个委托.");
            }),cts .Token );//cts .Token就是记录会在cath在把已取消的线程显示
 
  

 //这种不会卡界面        

while (task.Count(r => r.IsCompleted) < task.Count())//等待所有线程都完成后就退出循环
{
	lb_out.Text = @"筛选中……";
	lb_out.ForeColor = Color.Blue;
	System.Threading .Thread . Sleep(500);
 }

    Task Fun带返回值的方法使用

  List> task = new List>();
            foreach (string[,] t in snMac)
            {
                task.Add ( Task.Factory.StartNew(() => Test(t, folderAll)));
            }


            Task.WaitAll(task.ToArray());
            foreach (var   itmes in task)
            {
                txt_out.AppendText(itmes.Result);//取值
            }

th.join();方法

 在哪个线程中执行就会阻塞哪个线程,直到th执行完成后才会继续执行.

 ThreadPool.QueueUserWorkItem 线程池,本身是后台线程.放在不用人为去管它,而且很快就执行完的地方.不用start自动开始执行.

            ThreadPool.QueueUserWorkItem((ob) =>
            {
                for (int i = 0; i < 50; i++)
                {
                    lblist[0].Invoke(new Action(() =>
                    {
                        lblist[0].Text = i.ToString();
                    }));
                    Thread.Sleep(100);
                }
            });

多线程跨线程访问:

                        if (lblist[i].InvokeRequired)//判断是不是要调用Invoke方法(跨线程访问true为要调用,反之……)
                        {
                            //lblist[i].Invoke(new Action(s => { lblist[i].Text = s; }), str);
                            lblist[i].Invoke(new Action(() => { lblist[i].Text = str; }));
                        }
                        else
                        {
                            lblist[i].Text = str;
                        }

多线程同步锁:(独占对象)

                    lock();//只能锁定引用不能锁定值类型,比如可以锁list,数组,静态变量.objet、this.,锁住同一个对象(引用地址)就会互斥.

锁定时要考虑到底要锁什么对象,是为了锁定内容在使用时不被其它多线程修改.

为什么锁不了值型?

如果你传一个值类型,会装箱,下次代码运行到这里,又会装箱,两次不是同一个对象,所以锁不住.

异步委托

            Func length = (aa, bb) => aa.Length + bb.Length; //声明一个有参数和有返回值的委托
            IAsyncResult cc = length.BeginInvoke("654646", "654654+45", null, null);//异步调用
while (!cc.IsCompleted) { out.text="还没有完成,等待中"};//如果cc.IsCompleted==true那就是执行完了,可以放在特殊的地方确认状态  
            int dd = length.EndInvoke(cc);//等待调用的结果,这里会阻塞主线程,一直在这里等着

带回调的异步委托

            button1.Enabled = false;
            Func length = ((aa, bb) =>
            {
                Thread.Sleep(2000);
                return aa.Length + bb.Length;
            });
          length.BeginInvoke("654646", "654654+45", Deletgate_Next, length);
MessageBox.Show("这里是主线程");

        public void Deletgate_Next(IAsyncResult o)//回调函数,传回来的是length
        {
            var del = (Func) o.AsyncState;//将o接口对象转为对应的实例对象
            int value = del.EndInvoke(o);                                 //等待结果
            MessageBox.Show(value.ToString());
            if (button1.InvokeRequired)
            {  button1.Invoke(new Action(() => { button1.Enabled = true; })); }
        }
}//这里的执行流程会是,先调用异步线程,然后主线程继续执行,然后在回调函数里执行异步委托的结果
//下面是使用Action委托

        private void button2_Click(object sender, EventArgs e)
        {
            string srt = "";
            Action length = ((aa, bb) =>
            {
                Thread.Sleep(2000);
                srt = aa + bb;
            });
            length.BeginInvoke("546545", "65465w", MyAsyncCallback, length);
            MessageBox.Show("主函数");
        }


        public void MyAsyncCallback(IAsyncResult result)
        {
            Action del = (Action)result.AsyncState;
            del.EndInvoke(result);
            MessageBox.Show("异步回调函数");
        }

 Parallel下面有三个常用的方法invoke,For和ForEach。

            Thread th=new Thread (()=>{
                Parallel.Invoke(new Action(() =>
                {
                    for (int i = 0; i < 100; i++)
                    {
                        Console.WriteLine(i);
                        Thread.Sleep(1000);
                    }
                }), new Action(() =>
                {
                    for (int i = 100; i < 200; i++)
                    {
                        Console.WriteLine(i);
                        Thread.Sleep(1000);
                    }
                }));
                MessageBox.Show(sw.Elapsed.Seconds.ToString());
                sw.Stop();
            });

//可以样多个方法在最快的时间里所有代码一起执行,可以看出方法是并行执行的,执行效率提高了很多。调度时发现会阻塞主线程,最好配合多线程一起执行.



            Parallel.For(0, 50, new Action(i =>
            {
                lblist[1].Invoke(new Action(() =>
                {
                    // lblist[1].Text = i.ToString();
                    Console.Write(i.ToString()+"\r\n");
                }));
               // Thread.Sleep(1000);
            }));




 
  
 
 

你可能感兴趣的:(C#)