(7)C#里的线程和流
C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有多线程创建额外的线程。这里的一个简单的例子及其输出:
调用Start方法后,线程开始运行,线程一直到它所调用的方法返回后结束。
命名线程
线程可以通过它的Name属性进行命名,这非产有利于调试:可以用Console.WriteLine打印出线程的名字,Microsoft Visual Studio可以将线程的名字显示在调试工具栏的位置上。线程的名字可以在被任何时间设置——但只能设置一次,重命名会引发异常。
程序的主线程也可以被命名,下面例子里主线程通过CurrentThread命名:
没想到看不见的线程可以通过名字来区分,真是太可爱了。。
为了强化大家对线程的理解,再附上一个例子:
该示例创建一个名为 Worker 的类,该类包含辅助线程将执行的方法 DoWork。这实际上是辅助线程的 Main 函数。辅助线程将通过调用此方法来开始执行,并在此方法返回时自动终止。既然线程如此强大,为什么不多整几个呢?这里又引出了另一个问题。。。
何时使用多线程
多线程程序一般被用来在后台执行耗时的任务。主线程保持运行,并且工作线程做它的后台工作。对于Windows Forms程序来说,如果主线程试图执行冗长的操作,键盘和鼠标的操作会变的迟钝,程序也会失去响应。由于这个原因,应该在工作线程中运行一个耗时任务时 添加一个工作线程,即使在主线程上有一个有好的提示“处理中...”,以防止工作无法继续。这就避免了程序出现由操作系统提示的“没有相应”,来诱使用户 强制结束程序的进程而导致错误。模式对话框还允许实现“取消”功能,允许继续接收事件,而实际的任务已被工作线程完成。BackgroundWorker恰好可以辅助完成这一功能。
何时不要使用多线程
多线程也同样会带来缺点,最大的问题是它使程序变的过于复杂,拥有多线程本身并不复杂,复杂是的线程的交互作用,这带来了无论是否交互是否是有意的,都会 带来较长的开发周期,以及带来间歇性和非重复性的bugs。因此,要么多线程的交互设计简单一些,要么就根本不使用多线程。除非你有强烈的重写和调试欲 望。当用户频繁地分配和切换线程时,多线程会带来增加资源和CPU的开销。
多线程的应用十分广泛,但是有利有弊,大家编程的时候注意平衡就好。
下面讲下自己学习“流”的一些心得,在我看来,C#的数据传输都是靠流来实现,数据随着涓涓细流流向他们该去的地方,精确无误,十分高效。特别是文件的传输,万万离不开流。
MemoryStream类用于向内存而不是磁盘读写数据。MemoryStream封装以无符号字节数组形式存储的数据,该数组在创建 MemoryStream对象时被初始化,或者该数组可创建为空数组。可在内存中直接访问这些封装的数据。内存流可降低应用程序中对临时缓冲区和临时文件 的需要。
memoryStream的使用实例:
using System;
using System.IO;
using System.Text;
class program{
static void Main()
{
int count;
byte[] byteArray;
char[] charArray;
UnicodeEncoding uniEncoding=new UnicodeEncoding();
byte[] firstString=uniEncoding.GetBytes("努力学习");
byte[] secondString=uniEncoding.GetBytes("不做C#中的菜鸟");
using (MemoryStream memStream=new MemoryStream(100))
{
memStream.Write(firstString,0,firstString.Length);
count=0;
while(count<secondString.Length)
{
memStream.WriteByte(secondString[count++]);
}
Console.WriteLine("Capacity={0},Length={1},Position={2}\n",memStream.Capacity.ToString(),memStream.Length.ToString(),memStream.Position.ToString());
memStream.Seek(0, SeekOrigin.Begin);
byteArray=new byte[memStream.Length];
count=memStream.Read(byteArray,0,20);
while(count<memStream.Length)
{
byteArray[count++]=Convert.ToByte(memStream.ReadByte());
}
charArray=new char[uniEncoding.GetCharCount(byteArray,0,count)];
uniEncoding.GetDecoder().GetChars(byteArray,0,count,charArray,0);
Console.WriteLine(charArray);
Console.ReadKey();
}
}
}
关于文件流的写入与读出,这里提供给读者两个代码片段:
文件流写入:
private void btnChooseOpenFile_Click(object sender, EventArgs e)
{
//选择文本框 对象
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"C:\Users\John\Desktop";
//如果用户确定
if (ofd.ShowDialog() == DialogResult.OK)
{
//将用户选择的文件路径显示在文本框上
txtFilePathOpen.Text = ofd.FileName;
}
}
//保存文件
private void btnSave_Click(object sender, EventArgs e)
{
string strContent = txtInputSave.Text.Trim();
//创建文件流(文件路径,文件操作、创建)
using (FileStream fs = new FileStream(txtFilePathOpen.Text, FileMode.Create))
{
//将字符串字符串转成byte数组
byte[] byteFile = Encoding.UTF8.GetBytes(strContent);
//参数:要写到文件的数据数组,从第几个开始写,一共写多少个
fs.Write(byteFile, 0, byteFile.Length);
MessageBox.Show("保存成功!");
}
}
文件流读出:
private void btnChooseOpenFile2_Click(object sender, EventArgs e)
{
//选择文本框 对象
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"C:\Users\John\Desktop";
//如果用户确定
if (ofd.ShowDialog() == DialogResult.OK)
{
//将用户选择的文件路径显示在文本框上
txtFilePathOpen2.Text = ofd.FileName;
}
}
private void btnRead_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream(txtFilePathOpen2.Text, FileMode.Open))
{
byte[] byteData = new byte[1024 * 1024 * 4];
//返回读取的长度
int length=fs.Read(byteData,0,byteData.Length);
if (length > 0)
{
string strData = Encoding.UTF8.GetString(byteData);
txtOutputRead.Text = strData;
MessageBox.Show("读取成功");
}
}
}
目前我对流的理解止步于此,不过今后我会对这方面多加关注,如果这篇博客有什么不对的地方,还望大家指出,共同学习,一起进步。
转载于:https://www.cnblogs.com/shenyuelong/p/4477620.html
(7)C#里的线程和流相关推荐
- c++thread里暂停线程_多线程技术
1.程序 程序(Program)"是一个静态的概念,一般对应于操作系统中的一个可执行文件,比如:我们要启动酷狗听音乐,则对应酷狗的可执行程序.当我们双击酷狗,则加载程序到内存中,开始执行该程 ...
- android代码里 写线程,在Android线程池里运行代码任务实例
本节展示如何在线程池里执行任务.流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行. ...
- 如何关闭线程池?会创建不会关闭?调用关闭方法时线程池里的线程如何反应?
前言 相信大家在面试的时候经常会遇到「线程池」相关的问题,比如: 什么是线程池?线程池的优点? 有哪几种创建线程池的方式? 四种创建线程池的使用场景? 线程池的底层原理? 线程池相关的参数,比如Cor ...
- java线程读取流的时候卡死,java – 线程中断没有结束阻塞调用输入流读取
我正在使用RXTX从串口读取数据.读取是在以下列方式生成的线程内完成的: CommPortIdentifier portIdentifier = CommPortIdentifier.getPortI ...
- 简短总结一下C#里跨线程更新UI
简短总结一下C#里跨线程更新UI 摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问 ...
- 积跬步而至千里,积小流而成江海
2011年2月16日,开通了CSDN的博客,坚持每隔一段时间写一写文章,把自己在工作中碰到的一些问题摊上来讨论讨论,同时也为以后碰到同类问题提供快速检索. 深以为技术的积累不是一天两天的事,冰冻三尺非 ...
- iOS开发里的线程安全机制
[编者按]本文为再读苹果<Threading Programming Guide>笔记第四篇,主要分享了线程安全机制以及设计时所需要注意的事项.从最初的"什么是线程"到 ...
- c++thread里暂停线程_C语言如何正确的终止正在运行的子线程
最近开发一些东西,线程数非常之多,当用户输入Ctrl+C的情形下,默认的信号处理会把程序退出,这时有可能会有很多线程的资源没有得到很好的释放,造成了内存泄露等等诸如此类的问题,本文就是围绕着这么一个使 ...
- 面试官:一个线程OOM,进程里其他线程还能运行么?
作者:孤独烟,资深后端工程师,业内知名原创作者! 引言 这题是一个网友@大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题.大致如下 一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运 ...
最新文章
- showModalDialog 传值及刷新
- [设计模式随意链接]——命令模式
- chrome自动提交文件_实用!8个 chrome插件玩转GitHub,单个文件下载小意思
- C#弹窗提示并自动关闭方法
- java 大文件 处理_用Java处理大文件
- STMF4x 固件库V1.25.0
- SOA为什么不“香”了? | 大咖说中台
- 基于JavaSpringmvc+myabtis+html的鲜花商城系统设计和实现
- 计算机网络学习笔记:第二章
- Android ListView中 每一项都有不同的布局
- html标签之间去掉空白,html – 减少两个标签之间的空白差距
- 网易的企业免费邮箱和腾讯的企业邮箱
- 新萝卜家园windows xp 安装之后fonts中字体在 word ps中不显示
- 轻仓的贵金属白银今日走势分析
- 动态设置Button图片大小
- Havij 1.152 最新破解版
- 用MFC编程时在源文件里经常看到的AFX或afx是什么意思?
- 简单的java文档扫描器
- 所有程序员会面临的问题:程序员只能吃青春饭?
- sql升序null排在顶部