C#多线程⽂件读写整理总结
多线程读写⽂件⼀直是⼀个⽐较常⽤的技术,普通的锁显得效率低下,和单线程感觉基本没有啥区别,这⾥参考了⼤⽜的代码,采⽤了线程池技术,⼩菜我⼀直不明⽩异步和多线程有啥区别,后来读了个⼤⽜的博客,才明⽩,为加强理解,抄袭⼀下吧,
多线程相关名词概念的解释
并发:在操作系统中,是指⼀个时间段中有⼏个程序都处于已启动运⾏到运⾏完毕之间,且这⼏个程序都是在同⼀个处理机上运⾏。
其中两种并发关系分别是同步和互斥
互斥:进程间相互排斥的使⽤临界资源的现象,就叫互斥。
同步:进程之间的关系不是相互排斥临界资源的关系,⽽是相互依赖的关系。进⼀步的说明:就是前⼀个进程的输出作为后⼀个进程的输⼊,当第⼀个进程没有输出时第⼆个进程必须等待。具有同步关系的⼀组并发进程相互发送的信息称为消息或事件。
其中并发⼜有伪并发和真并发,伪并发是指单核处理器的并发,真并发是指多核处理器的并发。
并⾏:在单处理器中多道程序设计系统中,进程被交替执⾏,表现出⼀种并发的外部特种;在多处理器系统中,进程不仅可以交替执⾏,⽽且可以重叠执⾏。在多处理器上的程序才可实现并⾏处理。从⽽可知,并⾏是针对多处理器⽽⾔的。并⾏是同时发⽣的多个并发事件,具有并发的含义,但并发不⼀定并⾏,也亦是说并发事件之间不⼀定要同⼀时刻发⽣。
多线程:多线程是程序设计的逻辑层概念,它是进程中并发运⾏的⼀段代码。多线程可以实现线程间的切换执⾏。
异步:异步和同步是相对的,同步就是顺序执⾏,执⾏完⼀个再执⾏下⼀个,需要等待、协调运⾏。异步就是彼此独⽴,在等待某事件的过程中继续做⾃⼰的事,不需要等待这⼀事件完成后再⼯作。线程就是实现异步的⼀个⽅式。异步是让调⽤⽅法的主线程不需要同步等待另⼀线程的完成,从⽽可以让主线程⼲其它的事情。
异步和多线程并不是⼀个同等关系,异步是最终⽬的,多线程只是我们实现异步的⼀种⼿段。异步是当⼀个调⽤请求发送给被调⽤者,⽽调⽤者不⽤等待其结果的返回⽽可以做其它的事情。实现异步可以采⽤多线程技术或则交给另外的进程来处理。
如果都是独占cpu 的业务,⽐如举杠铃的业务,在单核情况下多线和单线没有区别。
总结
1. 多线程的好处:⽐较容易的实现了异步切换的思想,
2. 多线程本⾝程还是以同步完成,但是应该说⽐效率是⽐不上异步的。
3. 多核的好处,就是可以同时做事情,这个和单核完全不⼀样的。
线程池异步读写⽂件
废话不说了,直接上代码,很好理解的
1
class Program
{
static void Main(string[] args)
{
//把线程池的最⼤值设置为1000
ThreadPool.SetMaxThreads(1000, 1000);
ThreadPoolMessage("Start");
#region 异步写⽂件
//新⽴⽂件
FileStream stream0 = new FileStream("", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
byte[] bytes = new byte[16384];
string message = "An ";
bytes = Encoding.Unicode.GetBytes(message);
//启动异步写⼊
stream0.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(CallbackWrite), stream0);
stream0.Flush();
#endregion
//----------------------------------------------------
#region 异步读⽂件
byte[] byteData = new byte[80961024];
FileStream stream1 = new FileStream("", FileMode.OpenOrCreate,FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
/*把FileStream对象,byte[]对象,
长度等有关数据绑定到FileData对象中,
以附带属性⽅式送到回调函数
*/
FileData fileData = new FileData();
fileData.Stream = stream1;
fileData.Length = (int)stream1.Length;
fileData.ByteData = byteData;
//启动异步读取
stream1.BeginRead(byteData, 0, fileData.Length, new AsyncCallback(CallbackRead), fileData);
#endregion
Console.ReadKey();
}
/// <summary>
/// 写⽂件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackWrite(IAsyncResult result)
{
//显⽰线程池现状
Thread.Sleep(200);
ThreadPoolMessage("CallbackWrite");
//结束异步写⼊
FileStream stream = (FileStream)result.AsyncState;
stream.EndWrite(result);
stream.Close();
}
//显⽰线程池现状
static void ThreadPoolMessage(string data)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("{0}\n CurrentThreadId is {1}\n " +"WorkerThreads is:{2} CompletionPortThreads is :{3}",
data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
Console.WriteLine(message);
}
public class FileData
{
public FileStream Stream;
public int Length;
public byte[] ByteData;
}
/// <summary>
/// 读⽂件的回调函数
/// </summary>
/// <param name="result"></param>
static void CallbackRead(IAsyncResult result)
{
ThreadPoolMessage("CallbackRead");
,以FileStream.EndRead完成异步读取
log4j2 异步写文件FileData fileData = (FileData)result.AsyncState;
int length = fileData.Stream.EndRead(result);
fileData.Stream.Close();
//如果读取到的长度与输⼊长度不⼀致,则抛出异常
if (length != fileData.Length)
throw new Exception("Stream is not complete!");
string data = Encoding.ASCII.GetString(fileData.ByteData, 0, fileData.Length); Console.WriteLine(data.Substring(2, 22));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
1
</div><div><div></div></div>
<link href="csdnimg/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet"> </div>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论