WPF调用线程(二)复制文件并显示进度条
2011-04-03 22:42 杨延成 阅读(10726) 评论(3) 编辑 收藏 举报这一段时间要进行WPF及多线程的培训,于是就写了一个例子,主要功能是用复制文件时,显示进度条。以演示在WPF中,如何调用线程,基础理论就不多说了,园子里好多大牛都写过,MSDN也有详尽介绍,也可以查看我的前两篇文章,
C#线程基础
WPF调用线程(-)
也有一些介绍,先看运行效果
xaml如下:

<Window x:Class="WpfThreadTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Closed="Window_Closed" Loaded="Window_Loaded" Height="209" Width="537" ResizeMode="NoResize">
<Grid Height="186">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="132*" />
<ColumnDefinition Width="236*" />
<ColumnDefinition Width="147*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Name="textBlock1" Text="当前时间" Margin="35 10" Height="auto" Width="auto" />
<TextBox Grid.Column="1" Name="displayTimeByThread" Height="auto" Margin="0 10" />
<TextBlock Grid.Row="1" Name="textBlock2" Margin="35 10 0 10 " Text="源文件位置" />
<TextBox Grid.Column="1" Grid.Row="1" Name="srcFile" Margin="0 10" />
<TextBox Grid.Column="1" Grid.Row="2" Name="saveFilePath" Margin="0 10" />
<TextBlock Grid.Row="2" Name="textBlock3" Text="目标文件位置" Margin="35 10 0 10" />
<Button Content="..." Grid.Column="2" Grid.Row="1" Name="button1" Margin="10,10,66,10" Click="button1_Click" />
<Button Content="..." Grid.Column="2" Grid.Row="2" Name="button2" Margin="10,10,66,10" Height="23" Click="button2_Click"/>
<Button Content="开始时间线程" Grid.Column="2" Name="button3" Margin="10,10,35,10" Height="23" Click="button3_Click" />
<Button Content="开始文件Copy线程" Grid.Column="2" Grid.Row="3" Height="29" HorizontalAlignment="Left" Name="button4" VerticalAlignment="Top" Width="119" Click="button4_Click" />
<TextBlock Grid.Row="3" Name="copyFlag" Text="开始复制" />
<TextBlock Name="displayCopyInfo" Text="文件Copy进行中" Grid.Row="3" Grid.Column="1" />
<ProgressBar Grid.Column="1" Grid.Row="4" Margin="0 2" Height="8" Name="copyProgress" />
</Grid>
</Window>
后台CS

1 namespace WpfThreadTest
2 {
3 /// <summary>
4 /// MainWindow.xaml 的交互逻辑
5 /// </summary>
6 public partial class MainWindow : Window
7 {
8 Thread timeThread;
9 Thread copyThread;
10 public MainWindow()
11 {
12 InitializeComponent();
13 this.displayTimeByThread.Text = DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日 hh:mm:ss"); ;
14 timeThread = new Thread(new ThreadStart(DispatcherThread));
15 }
16 private void button3_Click(object sender, RoutedEventArgs e)
17 {
18 timeThread.Start();
19 }
20 public void DispatcherThread()
21 {
22 //可以通过循环条件来控制UI的更新
23 while (true)
24 {
25 ///线程优先级,最长超时时间,方法委托(无参方法)
26 displayTimeByThread.Dispatcher.BeginInvoke(
27 DispatcherPriority.Normal, new Action(UpdateTime));
28 Thread.Sleep(1000);
29 }
30 }
31
32
33 private void UpdateTime()
34 {
35 this.displayTimeByThread.Text = DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日 hh:mm:ss");
36 }
37
38 private void Window_Closed(object sender, EventArgs e)
39 {
40 ///关闭所有启动的线程
41 timeThread.Abort();
42 copyThread.Abort();
43 Application.Current.Shutdown();
44 }
45
46 private void button1_Click(object sender, RoutedEventArgs e)
47 {
48 ///设定要复制的文件全路径
49 OpenFileDialog openFile = new OpenFileDialog();
50 openFile.AddExtension = true;
51 openFile.CheckPathExists = true;
52 openFile.Filter = "*.rar|*.rar|all files|*.*";
53 openFile.FilterIndex = 0;
54 openFile.Multiselect = false;
55 bool? f=openFile.ShowDialog();
56 if (f!=null && f.Value)
57 {
58 this.srcFile.Text = openFile.FileName;
59 }
60 }
61
62 private void button2_Click(object sender, RoutedEventArgs e)
63 {
64 ///设定目标文件全路径
65 SaveFileDialog saveFile = new SaveFileDialog();
66 saveFile.AddExtension = true;
67 saveFile.Filter = "*.rar|*.rar|all files|*.*";
68 saveFile.FilterIndex = 0;
69
70 bool? f= saveFile.ShowDialog();
71 if (f != null && f.Value)
72 {
73 this.saveFilePath.Text = saveFile.FileName;
74 }
75 }
76
77 private void button4_Click(object sender, RoutedEventArgs e)
78 {
79 string fileName=this.srcFile.Text.Trim();
80 string destPath=this.saveFilePath.Text.Trim();
81 if(!File.Exists(fileName))
82 {
83 MessageBox.Show("源文件不存在");
84 return;
85 }
86
87 ///copy file and nodify ui that rate of progress of file copy
88 this.copyFlag.Text = "开始复制。。。";
89
90 //设置进度条最大值,这句代码写的有点郁闷
91 this.copyProgress.Maximum = (new FileInfo(fileName)).Length;
92
93 //保存复制文件信息,以进行传递
94 CopyFileInfo c = new CopyFileInfo() { SourcePath = fileName, DestPath = destPath };
95 //线程异步调用复制文件
96 copyThread = new Thread(new ParameterizedThreadStart(CopyFile));
97 copyThread.Start(c);
98
99 this.copyFlag.Text = "复制完成。。。";
100
101
102 }
103 /// <summary>
104 /// 复制文件的委托方法
105 /// </summary>
106 /// <param name="obj">复制文件的信息</param>
107 private void CopyFile(object obj)
108 {
109 CopyFileInfo c = obj as CopyFileInfo;
110 CopyFile(c.SourcePath, c.DestPath);
111 }
112 /// <summary>
113 /// 复制文件
114 /// </summary>
115 /// <param name="sourcePath"></param>
116 /// <param name="destPath"></param>
117 private void CopyFile( string sourcePath,string destPath)
118 {
119 FileInfo f = new FileInfo(sourcePath);
120 FileStream fsR = f.OpenRead();
121 FileStream fsW = File.Create(destPath);
122 long fileLength = f.Length;
123 byte[] buffer = new byte[1024];
124 int n = 0;
125
126 while (true)
127 {
128 ///设定线程优先级
129 ///异步调用UpdateCopyProgress方法
130 ///并传递2个long类型参数fileLength 与 fsR.Position
131 this.displayCopyInfo.Dispatcher.BeginInvoke(DispatcherPriority.SystemIdle,
132 new Action<long, long>(UpdateCopyProgress), fileLength, fsR.Position);
133
134 //读写文件
135 n=fsR.Read(buffer, 0, 1024);
136 if (n==0)
137 {
138 break;
139 }
140 fsW.Write(buffer, 0, n);
141 fsW.Flush();
142 Thread.Sleep(1);
143 }
144 fsR.Close();
145 fsW.Close();
146 }
147
148 private void UpdateCopyProgress(long fileLength,long currentLength)
149 {
150 this.displayCopyInfo.Text = string.Format("总大小:{0},已复制:{1}", fileLength, currentLength);
151 //刷新进度条
152 this.copyProgress.Value = currentLength;
153 }
154
155 private void Window_Loaded(object sender, RoutedEventArgs e)
156 {
157
158 }
159
160 }
161 public class CopyFileInfo
162 {
163 public string SourcePath { get; set; }
164 public string DestPath { get; set; }
165 }
166 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述