c#基础学习 - 线程,任务与同步
2018-02-07 02:22
295 查看
使用线程的几个原因, 假设从应用程序中进行网络调用需要一定时间,用户不希望分割用户界面,并长期等待,希望同时执行其他一些操作,或者取消发送给服务器的请求。这些可以用线程实现。
对于所有需要等待的操作,如文件,数据库或者网络访问带来的等待,可以启动一个新线程,同时完成其他任务。一个进程的多个线程可以同时运行与不同CPU,或者多核CPU的不同内核。 如果线程访问相同数据,必须实现同步机制,否则极易出错。
运行在服务器上的应用程序,带带客户请求的线程,成为侦听器线程,只要接收到请求,就把他传给另一个工作线程,之后继续与客户通讯。侦听器会立即返回,接收下一个客户发送的下一个请求。
进程包含资源: window句柄,文件系统句柄或其他内核对象。每个进程都分配了虚拟内存,一个进程至少包含一个线程,操作系统会调度线程,线程有一个优先级,正在处理的程序的位置计数器,一个存储局部变量的栈。 每个线程都有自己的栈,但程序代码的内存和堆有一个进程的所有线程共享,因为寻址都是在内存中完成,这使得线程间通讯非常的快。
1. 异步委托: 创建线程的一个简单的方法是定义委托, 并异步调用它,委托是方法的类型安全的引用,Delegate类还支持异步调用方法,在后台,委托类Delegate会创建一个执行任务的线程;委托使用线程池来完成异步操作。测试一下委托的异步特性, 从一个需要时间完成的方法测试,TasksAWhile()方法需要经过第2个变量
class Program
{
static void Main(string[] args)
{
//TakesAWhile(1, 10000);
TakesAWhileDelegate d1 = TakesAWhile; // 使用委托调用一次这个方法
d1(2, 1000);
Console.ReadKey();
}
public delegate int TakesAWhileDelegate(int data, int ms);
static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile started");
Thread.Sleep(ms);
Console.WriteLine("TakesAWhile completed");
return ++data;
}
}接下来如果后台执行这个委托的操作,在10秒的漫长等待中,在屏幕上打印"."应该如何操作呢? 使用"投票"技术,通过IAsyncResult检验委托是否完成了。 而开始调用委托,这是用委托的方法: BeginInvoke(),而BeginInvoke返回类型就是IAsyncResult,而BeginInvoke总是包含两个参数(object, AsyncCallback), IAsyncResult类型的返回对象,包含一个属性"IsCompleted", 用来判断委托是否完成任务;
只要委托没有完成,主线程就继续执行while循环。接下来程序改为:
static void Main(string[] args)
{
//TakesAWhile(1, 3000);
TakesAWhileDelegate d1 = TakesAWhile;
//开始调用委托:
IAsyncResult ar = d1.BeginInvoke(1, 10000, null, null);
while (!ar.IsCompleted)
{
Console.Write(".");
Thread.Sleep(50); //每次打点等待0.05秒
}
int result = d1.EndInvoke(ar); // 结束调用时要输入IAsyncResult类型的参数
Console.WriteLine("Result: {0}", result);
}以上是通过委托线程调用方法的基本例子,可以看到主线程和委托线程同时运行,在委托线程执行完毕后,主线程就停止循环。
处理等到线程完全结束,还可以通过等待句柄来判断是否结束,如果不用ar.IsCompleted, 主线程的循环会一直继续,如果设置循环一直跑下去,即使后台线程结束,主线程也不会结束。这是就需要ar.AsyncWaitHandle.WaitOne(time, false)来进行干预:
static void Main(string[] args)
{
//TakesAWhile(1, 3000);
TakesAWhileDelegate d1 = TakesAWhile;
//开始调用委托:
IAsyncResult ar = d1.BeginInvoke(1, 10000, null, null);
//while (!ar.IsCompleted)
while(true)
{
Console.Write(".");
if (ar.AsyncWaitHandle.WaitOne(50, true)) //50表示异步执行的时间间隔,true表示在等待之前是否退出同步域;
{
Console.Write(".");
//Thread.Sleep(50); //每次打点等待0.05秒
break;
}
}
int result = d1.EndInvoke(ar); // 结束调用时要输入IAsyncResult类型的参数
Console.WriteLine("Result: {0}", result);
Console.ReadKey();
}接下来看看回调方法的作用,作为等待结果的第三种方法,定义回调函数,并且在BeginInvok()方法的第三个参数中,可以传递一个满足AsyncCallback委托的需求方法
对于所有需要等待的操作,如文件,数据库或者网络访问带来的等待,可以启动一个新线程,同时完成其他任务。一个进程的多个线程可以同时运行与不同CPU,或者多核CPU的不同内核。 如果线程访问相同数据,必须实现同步机制,否则极易出错。
运行在服务器上的应用程序,带带客户请求的线程,成为侦听器线程,只要接收到请求,就把他传给另一个工作线程,之后继续与客户通讯。侦听器会立即返回,接收下一个客户发送的下一个请求。
进程包含资源: window句柄,文件系统句柄或其他内核对象。每个进程都分配了虚拟内存,一个进程至少包含一个线程,操作系统会调度线程,线程有一个优先级,正在处理的程序的位置计数器,一个存储局部变量的栈。 每个线程都有自己的栈,但程序代码的内存和堆有一个进程的所有线程共享,因为寻址都是在内存中完成,这使得线程间通讯非常的快。
1. 异步委托: 创建线程的一个简单的方法是定义委托, 并异步调用它,委托是方法的类型安全的引用,Delegate类还支持异步调用方法,在后台,委托类Delegate会创建一个执行任务的线程;委托使用线程池来完成异步操作。测试一下委托的异步特性, 从一个需要时间完成的方法测试,TasksAWhile()方法需要经过第2个变量
class Program
{
static void Main(string[] args)
{
//TakesAWhile(1, 10000);
TakesAWhileDelegate d1 = TakesAWhile; // 使用委托调用一次这个方法
d1(2, 1000);
Console.ReadKey();
}
public delegate int TakesAWhileDelegate(int data, int ms);
static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile started");
Thread.Sleep(ms);
Console.WriteLine("TakesAWhile completed");
return ++data;
}
}接下来如果后台执行这个委托的操作,在10秒的漫长等待中,在屏幕上打印"."应该如何操作呢? 使用"投票"技术,通过IAsyncResult检验委托是否完成了。 而开始调用委托,这是用委托的方法: BeginInvoke(),而BeginInvoke返回类型就是IAsyncResult,而BeginInvoke总是包含两个参数(object, AsyncCallback), IAsyncResult类型的返回对象,包含一个属性"IsCompleted", 用来判断委托是否完成任务;
只要委托没有完成,主线程就继续执行while循环。接下来程序改为:
static void Main(string[] args)
{
//TakesAWhile(1, 3000);
TakesAWhileDelegate d1 = TakesAWhile;
//开始调用委托:
IAsyncResult ar = d1.BeginInvoke(1, 10000, null, null);
while (!ar.IsCompleted)
{
Console.Write(".");
Thread.Sleep(50); //每次打点等待0.05秒
}
int result = d1.EndInvoke(ar); // 结束调用时要输入IAsyncResult类型的参数
Console.WriteLine("Result: {0}", result);
}以上是通过委托线程调用方法的基本例子,可以看到主线程和委托线程同时运行,在委托线程执行完毕后,主线程就停止循环。
处理等到线程完全结束,还可以通过等待句柄来判断是否结束,如果不用ar.IsCompleted, 主线程的循环会一直继续,如果设置循环一直跑下去,即使后台线程结束,主线程也不会结束。这是就需要ar.AsyncWaitHandle.WaitOne(time, false)来进行干预:
static void Main(string[] args)
{
//TakesAWhile(1, 3000);
TakesAWhileDelegate d1 = TakesAWhile;
//开始调用委托:
IAsyncResult ar = d1.BeginInvoke(1, 10000, null, null);
//while (!ar.IsCompleted)
while(true)
{
Console.Write(".");
if (ar.AsyncWaitHandle.WaitOne(50, true)) //50表示异步执行的时间间隔,true表示在等待之前是否退出同步域;
{
Console.Write(".");
//Thread.Sleep(50); //每次打点等待0.05秒
break;
}
}
int result = d1.EndInvoke(ar); // 结束调用时要输入IAsyncResult类型的参数
Console.WriteLine("Result: {0}", result);
Console.ReadKey();
}接下来看看回调方法的作用,作为等待结果的第三种方法,定义回调函数,并且在BeginInvok()方法的第三个参数中,可以传递一个满足AsyncCallback委托的需求方法
static void Main(string[] args) { TakesAWhileDelegate d1 = TakesAWhile; d1.BeginInvoke(1,3000, TakesAWhereCompleted, d1); for (int i = 0; i < 100; i++) { Console.Write("+"); Thread.Sleep(50); } } static void TakesAWhereCompleted(IAsyncResult ar) { if (ar == null) throw new ArgumentNullException("ar"); TakesAWhileDelegate d1 = ar.AsyncState as TakesAWhileDele 819a gate; Trace.Assert(d1!=null, "Invalid object type"); int result = d1.EndInvoke(ar); Console.WriteLine("result: {0}",result); } public delegate int TakesAWhileDelegate(int data, int ms); static int TakesAWhile(int data, int ms) { Console.WriteLine("TakesAWhile started"); Thread.Sleep(ms); Console.WriteLine("TakesAWhile completed"); return ++data; }
相关文章推荐
- C#基础之--线程、任务和同步:一、异步委托
- C#学习笔记之线程 - 同步上下文
- C#中的线程 -- 同步基础(同步本质,线程安全,线程中断)
- C#线程、任务和同步
- C#中的线程 -- 同步基础(同步本质,线程安全,线程中断)
- C#中的线程 -- 同步基础(线程状态,同步上下文)
- c#网络编程之TCP/IP(一)C#线程任务基础Thread
- 通过代码学习C#&.NET——委托使用(线程、任务)
- Java基础第十一天学习日记_线程、同步、死锁
- JAVA基础学习(十一)--多线程一线程的创建,运行,同步和锁
- C#学习笔记之线程 - 高级主题:非阻塞同步
- Java基础第十二天学习日记_线程、线程的同步、线程间通讯
- [C#基础]线程学习笔记(二)
- C#学习第八弹之线程基础理解
- ASP.NET Boilerplate 学习 AspNet Core2 浏览器缓存使用 c#基础,单线程,跨线程访问和线程带参数 wpf 禁用启用webbroswer右键菜单 EF Core 2.0使用MsSql/MySql实现DB First和Code First ASP.NET Core部署到Windows IIS QRCode.js:使用 JavaScript 生成
- 第一个WPF学习例子--多线程、任务和UI线程一起使用、方法重载 c#书籍
- Android基础学习之异步任务使用Thread(线程)
- C#中的线程 -- 同步基础(同步本质,线程安全,线程中断)
- C#基础学习:Thread创建线程
- C#之任务,线程和同步