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#里的线程和流相关推荐

  1. c++thread里暂停线程_多线程技术

    1.程序 程序(Program)"是一个静态的概念,一般对应于操作系统中的一个可执行文件,比如:我们要启动酷狗听音乐,则对应酷狗的可执行程序.当我们双击酷狗,则加载程序到内存中,开始执行该程 ...

  2. android代码里 写线程,在Android线程池里运行代码任务实例

    本节展示如何在线程池里执行任务.流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行. ...

  3. 如何关闭线程池?会创建不会关闭?调用关闭方法时线程池里的线程如何反应?

    前言 相信大家在面试的时候经常会遇到「线程池」相关的问题,比如: 什么是线程池?线程池的优点? 有哪几种创建线程池的方式? 四种创建线程池的使用场景? 线程池的底层原理? 线程池相关的参数,比如Cor ...

  4. java线程读取流的时候卡死,java – 线程中断没有结束阻塞调用输入流读取

    我正在使用RXTX从串口读取数据.读取是在以下列方式生成的线程内完成的: CommPortIdentifier portIdentifier = CommPortIdentifier.getPortI ...

  5. 简短总结一下C#里跨线程更新UI

    简短总结一下C#里跨线程更新UI 摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问 ...

  6. 积跬步而至千里,积小流而成江海

    2011年2月16日,开通了CSDN的博客,坚持每隔一段时间写一写文章,把自己在工作中碰到的一些问题摊上来讨论讨论,同时也为以后碰到同类问题提供快速检索. 深以为技术的积累不是一天两天的事,冰冻三尺非 ...

  7. iOS开发里的线程安全机制

    [编者按]本文为再读苹果<Threading Programming Guide>笔记第四篇,主要分享了线程安全机制以及设计时所需要注意的事项.从最初的"什么是线程"到 ...

  8. c++thread里暂停线程_C语言如何正确的终止正在运行的子线程

    最近开发一些东西,线程数非常之多,当用户输入Ctrl+C的情形下,默认的信号处理会把程序退出,这时有可能会有很多线程的资源没有得到很好的释放,造成了内存泄露等等诸如此类的问题,本文就是围绕着这么一个使 ...

  9. 面试官:一个线程OOM,进程里其他线程还能运行么?

    作者:孤独烟,资深后端工程师,业内知名原创作者! 引言 这题是一个网友@大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题.大致如下 一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运 ...

最新文章

  1. showModalDialog 传值及刷新
  2. [设计模式随意链接]——命令模式
  3. chrome自动提交文件_实用!8个 chrome插件玩转GitHub,单个文件下载小意思
  4. C#弹窗提示并自动关闭方法
  5. java 大文件 处理_用Java处理大文件
  6. STMF4x 固件库V1.25.0
  7. SOA为什么不“香”了? | 大咖说中台
  8. 基于JavaSpringmvc+myabtis+html的鲜花商城系统设计和实现
  9. 计算机网络学习笔记:第二章
  10. Android ListView中 每一项都有不同的布局
  11. html标签之间去掉空白,html – 减少两个标签之间的空白差距
  12. 网易的企业免费邮箱和腾讯的企业邮箱
  13. 新萝卜家园windows xp 安装之后fonts中字体在 word ps中不显示
  14. 轻仓的贵金属白银今日走势分析
  15. 动态设置Button图片大小
  16. Havij 1.152 最新破解版
  17. 用MFC编程时在源文件里经常看到的AFX或afx是什么意思?
  18. 简单的java文档扫描器
  19. 所有程序员会面临的问题:程序员只能吃青春饭?
  20. sql升序null排在顶部

热门文章

  1. 【学无止境】ajax长循环,反向ajax初体会,不用ws实现即时聊天
  2. eigrp ospf 邻居建立过程比较
  3. Bag of Tricks for Image Classification
  4. 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)
  5. Java 多线程初探(二) - 通讯与协调
  6. 殇-至吾爱 ---经典
  7. react-native-webview禁止缩放
  8. Go嵌套并发实现EDM,附坑点分析#1
  9. python 下载小说
  10. 微信公众号开发之网页授权认证获取用户的详细信息,实现自动登陆