b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

C# 多线程编程第一步(3)

电脑杂谈  发布时间:2019-06-18 09:11:23  来源:网络整理

多线程编程_线程与线程池_windows编程线程

执行结果:

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在executor接口中, 而submit()方法可以返回持有计算结果的future对象,它定义在executorservice接口中,它扩展了executor接口,其它线程池类像threadpoolexecutor和scheduledthreadpoolexecutor都有这些方法。两个方法都可以向线程池提交任务,execute ()方法的返回类型是 void,它定义在 executor 接口中, 而 submit ()方法可以返回持有计算结果的 future 对象,它定义在 executorservice 接口中多线程编程,它扩展了 executor 接口,其它线程池类像 threadpoolexecutor 和 scheduledthreadpoolexecutor 都有这些方法。两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在executor接口中,而submit()方法可以返回持有计算结果的future对象,它定义在executorservice接口中,它扩展了executor接口,其它线程池类像threadpoolexecutor和scheduledthreadpoolexecutor都有这些方法。

接下来我们看上面的执行结果。咦?为什么主线程没有“工作”呢?

这里你可以在异步委托调用的 Run() 方法里面为线程设置一个几秒钟或者更长的挂起时间。然后在设置监视对象这里设置一个小于线程挂起的时间,然后调试你就能发现问题的所在了。其实也不算是问题,只是之前的理解有误。

其实 WaitAll() 方法和WaitAny() 方法设置监视对象,然后指定一个时间(毫秒值),这里的意思是当所有的监视对象在指定的时间内都接收到信号时(这里是指 WaitAll() 方法),就不会执行 while 里面的主线程的工作,反之就会执行。

这里你可能会有疑问,如果是这样,那我把前面的逻辑非运算符去掉那不就相反了么。这么理解逻辑上是没错的,但是我还是要说的是,尽量不要去尝试,因为这会是个死循环。WaitAny() 这个方法也是一样的理解,不同的是,它不需要等到所有的监视对象都收到信号,它只需要一个监视对象收到信号就够了,这里就不在演示了。

上面的方法可以看出,我们虽然使用的是异步的方式调用的方法,但是依旧需要等待异步的方法返回执行的结果,尽管我们可以不阻塞主线程,但是还是觉得不太方便。所以也就有了本篇博客最后一个要点,异步委托的回调函数。

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);
static void Main(string[] args) { ThreadDemoClass demoClass = new ThreadDemoClass(); UserInfo userInfo = null; //创建一个委托并绑定方法 MyDelegate myDelegate = new MyDelegate(demoClass.Run); //创建一个回调函数的委托 AsyncCallback asyncCallback = new AsyncCallback(Complete); for (int i = 0; i < 3; i++) { userInfo = new UserInfo(); userInfo.Name = "Brambling" + i.ToString(); userInfo.Age = 33 + i; //传入参数并执行异步委托,并设置回调函数 IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, null); } Console.WriteLine("Main thread working..."); Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine(); Console.ReadKey(); } public static void Complete(IAsyncResult result) { UserInfo userInfoRes = null; AsyncResult asyncResult = (AsyncResult)result; //获取在其上调用异步调用的委托对象 MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate; //结束在其上调用的异步委托,并获取返回值 userInfoRes = myDelegate.EndInvoke(result); Console.WriteLine("My name is " + userInfoRes.Name); Console.WriteLine("I'm " + userInfoRes.Age + " years old this year"); Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId); } } public class ThreadDemoClass { public UserInfo Run(UserInfo userInfo) { userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Child thread working..."); Console.WriteLine("Child thread ID is:" + userInfo.ThreadId); Console.WriteLine(); return userInfo; } }

windows编程线程_多线程编程_线程与线程池

执行结果:

从上面可以看到主线程再执行了异步委托之后继续执行了下去,然后在回调函数里输出了信息,也就是说在调用了异步委托之后就不管了,把之后的结束委托和获取委托的返回值放到了回调函数中,因为回调函数是没有返回值的,但是回调函数可以有一个参数。上面说到的 BeginInvoke() 方法的最后两个参数,它的倒数第二个参数就是一个回调函数的委托,最后一个参数可以设置传入回调函数的参数。如下:

   class Program
    {
        //定义一个委托类
        private delegate UserInfo MyDelegate(UserInfo userInfo);
        static List<UserInfo> userInfoList = new List<UserInfo>();
        static void Main(string[] args)
        {
            ThreadDemoClass demoClass = new ThreadDemoClass();
            UserInfo userInfo = null;
            //创建一个委托并绑定方法
            MyDelegate myDelegate = new MyDelegate(demoClass.Run);
            //创建一个回调函数的委托
            AsyncCallback asyncCallback = new AsyncCallback(Complete);
            //回调函数的参数
            string str = "I'm the parameter of the callback function!";
            for (int i = 0; i < 3; i++)
            {
                userInfo = new UserInfo();
                userInfo.Name = "Brambling" + i.ToString();
                userInfo.Age = 33 + i;
                //传入参数并执行异步委托,并设置回调函数
                IAsyncResult result = myDelegate.BeginInvoke(userInfo, asyncCallback, str);
            }
            Console.WriteLine("Main thread working...");
            Console.WriteLine("Main thread ID is:" + Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine();
            
            Console.ReadKey();
        }
        public static void Complete(IAsyncResult result)
        {
            UserInfo userInfoRes = null;
            AsyncResult asyncResult = (AsyncResult)result;
            //获取在其上调用异步调用的委托对象
            MyDelegate myDelegate = (MyDelegate)asyncResult.AsyncDelegate;
            
            //结束在其上调用的异步委托,并获取返回值
            userInfoRes = myDelegate.EndInvoke(result);
            Console.WriteLine("My name is " + userInfoRes.Name);
            Console.WriteLine("I'm " + userInfoRes.Age + " years old this year");
            Console.WriteLine("Thread ID is:" + userInfoRes.ThreadId);
            //获取回调函数的参数
            string str = result.AsyncState as string;
            Console.WriteLine(str);
        }
    }
    public class ThreadDemoClass
    {
        public UserInfo Run(UserInfo userInfo)
        {
            userInfo.ThreadId = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Child thread working...");
            Console.WriteLine("Child thread ID is:" + userInfo.ThreadId);
            Console.WriteLine();
            return userInfo;
        }
    }

执行结果:

回调函数的参数也是 object 类型的,我这里用的是一个 string 类型,但是它也可以是自定义类型的参数。

而为了方便理解,后面描述中用“同步线程”指代与线程同步相关的线程,同样,用“异步线程”表示与线程异步相关的线程。 -- david a. patterson & john l. hennessy 并发编程模型的分类 java ,c# 共享内存 pthread,win32线程库并发编程 jvm上的scala 消息传递 google 的go ericsson的erlang 共享内存模型的线程间通信 通过共享变量 线程a 的写-读来通信 线程b首先,线程a写 然后,线程b读 共享内存空间 a 1 消息传递模型的线程间通信 线程之间通过明确 的发送消息来通信 线程a 线程a向b发送消息 线程b 读/写 读/写独立内存空间a 独立内存空间b a 1 b 2 它们就是想对着干。同时,在读到每一章节的时候,我会准备很多的资料来扩充自己的知识加深自己的理解,例如,我会去图书馆找出很多对某一惯例的理解性或是有案例分析的书籍,我并不会逐字逐句地来读这些书,而是把这些书当作辅助资料,当遇到某一知识点理解上有障碍的时候,我会找到相关的案例来加深自己对这些知识点的理解,知道理论是如何应用到实际当中,这样既能加深知识点在脑海中的印象又能应用自如。

参考:


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-106819-3.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...