using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ThreadAndDelegate
{
/*
Winform 中使用多线程实现文件复制操作,其中涉及到控件跨线程操作。
*/
public delegate void SetControlEnable();
public delegate void SetProgressBarValue(int value);
public delegate void SetProgressBarMaxValue(int value);
public partial class FileOperation_Thread : Form
{
long blockSize = -1;
string filePath = string.Empty;
public FileOperation_Thread()
{
InitializeComponent();
}
private void FileOperation_Thread_Load(object sender, EventArgs e)
{
this.comboBox1.SelectedIndex = 0;
blockSize = Convert.ToInt64(this.comboBox1.Text);
this.btnCopy.Enabled = false;
}
private void btnSelectFile_Click(object sender, EventArgs e)
{
openFileDialog1.Multiselect = false;
openFileDialog1.Title = "选择文件";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
this.txtBoxSource.Text = openFileDialog1.FileName;
}
}
private void btnFolder_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
txtBoxDest.Text = folderBrowserDialog1.SelectedPath;
}
}
private void btnCopy_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtBoxSource.Text))
{
MessageBox.Show("未选择源文件");
return;
}
if (string.IsNullOrWhiteSpace(txtBoxDest.Text))
{
MessageBox.Show("未指定目录");
return;
}
Thread threadOne = new Thread(RunCopy);
threadOne.Start();
}
private void txtBoxSource_TextChanged(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
if (string.IsNullOrWhiteSpace(tb.Text))
{
this.btnCopy.Enabled = false;
return;
}
this.btnCopy.Enabled = true;
}
private void RunCopy()
{
if (!Directory.Exists(this.txtBoxDest.Text.Trim()))
{
Directory.CreateDirectory(this.txtBoxDest.Text.Trim());
}
string sourcePath = this.txtBoxSource.Text.Trim();
string destPath = this.txtBoxDest.Text.Trim();
string fileName = sourcePath.Substring(sourcePath.LastIndexOf("\\") + 1);
byte[] content = new byte[blockSize];
FileStream readerStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
FileStream writerStream = new FileStream(destPath + "\\" + fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
long loop = readerStream.Length / blockSize;
long r = readerStream.Length % blockSize;
int ProcessMax = (int)loop;
if (InvokeRequired)
{
this.Invoke(new SetProgressBarMaxValue(SetMaxValue), r != 0 ? ++ProcessMax : ProcessMax);
}
else
{
this.progressBar1.Value = r != 0 ? ++ProcessMax : ProcessMax;
}
for (int i = 0; i < loop; i++)
{
readerStream.Read(content, 0, content.Length);
writerStream.Write(content, 0, content.Length);
try
{
if (InvokeRequired)
{
this.Invoke(new SetProgressBarValue(SetEnable), i + 1);
}
else
{
this.progressBar1.Value = i + 1;
}
}
catch
{
Thread.CurrentThread.Abort();
}
}
if (r != 0)
{
long remain = readerStream.Length - loop * blockSize;
content = new byte[remain];
readerStream.Read(content, 0, content.Length);
writerStream.Write(content, 0, content.Length);
try
{
if (InvokeRequired)
{
this.Invoke(new SetProgressBarValue(SetEnable), Convert.ToInt32(loop + 1));
}
else
{
this.progressBar1.Value = Convert.ToInt32(loop + 1);
}
}
catch
{
Thread.CurrentThread.Abort();
}
}
readerStream.Flush();
writerStream.Flush();
readerStream.Close();
writerStream.Close();
DialogResult result = MessageBox.Show("拷贝成功!");
if (result == DialogResult.OK)
{
if (InvokeRequired)
{
this.Invoke(new SetControlEnable(SetEnable));
}
else
{
this.btnSearch.Enabled = true;
}
Thread.CurrentThread.Abort();
}
}
private void SetMaxValue(int value)
{
this.progressBar1.Maximum = value;
progressBar1.Visible = true;
}
private void SetEnable(int value)
{
progressBar1.Value = value;
if (progressBar1.Value == progressBar1.Maximum)
{
Thread.Sleep(1000);
progressBar1.Visible = false;
}
}
private void SetEnable()
{
this.btnSearch.Enabled = true;
filePath = this.txtBoxDest.Text.Trim();
}
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
blockSize = Convert.ToInt64(this.comboBox1.Text);
}
private void btnSearch_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(filePath);
}
}
}
设计效果:
运行效果: