代码改变世界

WPF调用线程(二)复制文件并显示进度条(2)

2011-04-04 14:19  杨延成  阅读(2343)  评论(0编辑  收藏  举报

这篇文章,是上一篇的修改版,将进度条的更新也委托给了另外一个线程。由此也进行线程同步,通信等功能

前台代码没有改变,参考:

WPF调用线程(二)复制文件并显示进度条

后台代码:

1 namespace WpfThreadTest
2 {
3 /// <summary>
4 /// ThreadCommunication.xaml 的交互逻辑
5 /// </summary>
6   public partial class ThreadCommunication : Window
7 {
8 Thread timeThread;
9 Thread copyThread;
10 Thread updateCopyProgressThread;
11 ManualResetEvent mEvent = new ManualResetEvent(true);
12 //判断线程安全退出的信号量
13   ManualResetEvent mEventStopAll = new ManualResetEvent(false);
14
15 public ThreadCommunication()
16 {
17 InitializeComponent();
18 this.displayTimeByThread.Text = DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日 hh:mm:ss");
19 timeThread = new Thread(new ThreadStart(DispatcherThread));
20 }
21 private void button3_Click(object sender, RoutedEventArgs e)
22 {
23 timeThread.Start();
24 }
25 public void DispatcherThread()
26 {
27 //可以通过循环条件来控制UI的更新
28   while (true)
29 {
30 ///线程优先级,最长超时时间,方法委托(无参方法)
31 displayTimeByThread.Dispatcher.BeginInvoke(
32 DispatcherPriority.Normal, new Action(UpdateTime));
33 Thread.Sleep(1000);
34 }
35 }
36
37
38 private void UpdateTime()
39 {
40 this.displayTimeByThread.Text = DateTime.Now.ToLocalTime().ToString("yyyy年MM月dd日 hh:mm:ss");
41 }
42
43 private void Window_Closed(object sender, EventArgs e)
44 {
45 ///关闭所有启动的线程
46 timeThread.Abort();
47 copyThread.Abort();
48 updateCopyProgressThread.Abort();
49 Application.Current.Shutdown();
50 }
51
52 private void button1_Click(object sender, RoutedEventArgs e)
53 {
54 ///设定要复制的文件全路径
55 OpenFileDialog openFile = new OpenFileDialog();
56 openFile.AddExtension = true;
57 openFile.CheckPathExists = true;
58 openFile.Filter = "*.rar|*.rar|all files|*.*";
59 openFile.FilterIndex = 0;
60 openFile.Multiselect = false;
61 bool? f=openFile.ShowDialog();
62 if (f!=null && f.Value)
63 {
64 this.srcFile.Text = openFile.FileName;
65 }
66 }
67
68 private void button2_Click(object sender, RoutedEventArgs e)
69 {
70 ///设定目标文件全路径
71 SaveFileDialog saveFile = new SaveFileDialog();
72 saveFile.AddExtension = true;
73 saveFile.Filter = "*.rar|*.rar|all files|*.*";
74 saveFile.FilterIndex = 0;
75
76 bool? f= saveFile.ShowDialog();
77 if (f != null && f.Value)
78 {
79 this.saveFilePath.Text = saveFile.FileName;
80 }
81 }
82
83 private void button4_Click(object sender, RoutedEventArgs e)
84 {
85 string fileName=this.srcFile.Text.Trim();
86 string destPath=this.saveFilePath.Text.Trim();
87 if(!File.Exists(fileName))
88 {
89 MessageBox.Show("源文件不存在");
90 return;
91 }
92
93 ///copy file and nodify ui that rate of progress of file copy
94 this.copyFlag.Text = "开始复制。。。";
95
96 //设置进度条最大值,这句代码写的有点郁闷
97 this.copyProgress.Maximum = (new FileInfo(fileName)).Length;
98
99 //保存复制文件信息,以进行传递
100 CopyFileInfo c = new CopyFileInfo() { SourcePath = fileName, DestPath = destPath };
101 //线程异步调用复制文件
102 copyThread = new Thread(new ParameterizedThreadStart(CopyFile));
103 copyThread.Start(c);
104
105 updateCopyProgressThread = new Thread(new ThreadStart(NodifyUpdate));
106 updateCopyProgressThread.Start();
107
108 this.copyFlag.Text = "复制完成。。。";
109
110
111 }
112 /// <summary>
113 /// 复制文件的委托方法
114 /// </summary>
115 /// <param name="obj">复制文件的信息</param>
116 private void CopyFile(object obj)
117 {
118 CopyFileInfo c = obj as CopyFileInfo;
119 CopyFile(c.SourcePath, c.DestPath);
120 }
121 /// <summary>
122 /// 复制文件
123 /// </summary>
124 /// <param name="sourcePath"></param>
125 /// <param name="destPath"></param>
126 private void CopyFile( string sourcePath,string destPath)
127 {
128 FileInfo f = new FileInfo(sourcePath);
129 FileStream fsR = f.OpenRead();
130 FileStream fsW = File.Create(destPath);
131 BasicCopyInfo.FileLength = f.Length;
132 byte[] buffer = new byte[1024];
133 int n = 0;
134
135 while (true)
136 {
137 ///向另一个线程通信,传递数据
138 ///
139 mEvent.Reset();
140 BasicCopyInfo.CurrentLength = fsR.Position;
141 mEvent.Set();
142
143 //读写文件
144 n=fsR.Read(buffer, 0, 1024);
145 if (n==0)
146 {
147 break;
148 }
149 fsW.Write(buffer, 0, n);
150 fsW.Flush();
151 Thread.Sleep(1);
152 }
153 fsR.Close();
154 fsW.Close();
155 }
156
157
158 private void NodifyUpdate()
159 {
160 ///阻止当前线程,直到收到通知
161 while (mEvent.WaitOne())
162 {
163 ///设定线程优先级
164 ///异步调用UpdateCopyProgress方法
165 ///并传递2个long类型参数fileLength 与 fsR.Position
166 this.displayCopyInfo.Dispatcher.BeginInvoke(DispatcherPriority.SystemIdle,
167 new Action<long, long>(UpdateCopyProgress),BasicCopyInfo.FileLength, BasicCopyInfo.CurrentLength);
168
169 System.Threading.Thread.Sleep(1);
170 }
171 }
172
173 /// <summary>
174 /// 更新进度条
175 /// </summary>
176 /// <param name="fileLength"></param>
177 /// <param name="currentLength"></param>
178
179 private void UpdateCopyProgress(long fileLength,long currentLength)
180 {
181 this.displayCopyInfo.Text = string.Format("总大小:{0},已复制:{1}", fileLength, currentLength);
182 //刷新进度条
183 this.copyProgress.Value = currentLength;
184 }
185
186 private void Window_Loaded(object sender, RoutedEventArgs e)
187 {
188 this.srcFile.Text = "F:\\source.txt";
189 this.saveFilePath.Text = "F:\\abc.txt";
190 }
191
192 }
193 public class BasicCopyInfo
194 {
195 public static long CurrentLength { get; set; }
196 public static long FileLength { get; set; }
197 }
198 public class CopyFileInfo
199 {
200 public string SourcePath { get; set; }
201 public string DestPath { get; set; }
202 }
203 }