首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

线程的交叉有关问题

2013-07-20 
线程的交叉问题:全部代码:using Systemusing System.Collections.Genericusing System.ComponentModelu

线程的交叉问题:
全部代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace BatchChangeImgFormat {
    public partial class Form1: Form {
        #region
        private string[] picNames = null;    //选择转换的所有图片路径.
        private string strSavePath = null;  //转换后存储的路径.
        private int nFormat;    //标志选择转换的格式.
        private Bitmap bMap;    //转换用的BitMap.
        #endregion
        public Form1() {
            InitializeComponent();
            tsbtn_Open.Click += (sender, e) => InitializeSelectedPics(sender, e);   //加载图片.
            this.Load += (sender, e) => { tscombox_ChangeFormat.SelectedIndex = 0; };   //初始选择第一项.
            tsbtnClear.Click += (sender, e) => ClearSelectedPic(sender, e); //清空列表.
            tsbtn_Save.Click += (sender, e) => StorePathAfterChanged(sender, e);//存储转换后保存图片的路径.
            tsbtnStart.Click += (sender, e) => ConvertFormatSelected(sender, e);    //开始转换.
            tsbtnClose.Click += (sender, e) => CloseForm(sender, e);    //关闭.
        }

        //加载需要转换的图片.
        void InitializeSelectedPics(object sender, EventArgs e) {
            openFD.Filter = "所有图片|*.jpg;*.jpeg;*.gif;*.bmp;*.png";
            if(openFD.ShowDialog() != DialogResult.OK) return;


            string[] items = new string[7]; //存储每行项的信息.
            picNames = openFD.FileNames;  //存储需要转换的图片.
            foreach(var pic in picNames) {
                FileInfo p = new FileInfo(pic);
                imgList.Images.Add(p.Name, Properties.Resources.done);    //显示"已完成加载"的图片.
                items[1] = p.Name;
                items[2] = p.Extension;
                items[3] = p.CreationTime.ToLongDateString();
                items[4] = p.DirectoryName;
                items[5] = (p.Length / 1024) + " KB";
                items[6] = "未转换";
                ListViewItem lvItem = new ListViewItem(items, p.Name);  //加载子项,并制定图像的键.
                lv.Items.Add(lvItem);
            }
            labCount.Text = string.Format("共加载 {0} 张图片", picNames.Length);
        }

        //存储转换后保存图片的路径.
        void StorePathAfterChanged(object sender, EventArgs e) {
            if(folderBD.ShowDialog() != DialogResult.OK) return;
            strSavePath = folderBD.SelectedPath;
        }

        //清空列表.
        void ClearSelectedPic(object sender, EventArgs e) {
            DialogResult dResult = MessageBox.Show("确认要清空当前列表?", "警告", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);


            if(dResult == DialogResult.Yes) {
                picNames = null;    //清除保存的图片路径.
                lv.Items.Clear();
            }
        }

        //关闭.
        void CloseForm(object sender, EventArgs e) {
            DialogResult dResult = MessageBox.Show("确认关闭?", "警告", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
            if(dResult == DialogResult.Yes)
                Application.Exit();
        }

        //单击"开始转换".
        void ConvertFormatSelected(object sender, EventArgs e) {
            if(lv.Items.Count <= 0) {
                MessageBox.Show("请先加载图片!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            if(string.IsNullOrEmpty(strSavePath)) {
                MessageBox.Show("请先选择转换后保存的路径", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            string formatSelected = (string)tscombox_ChangeFormat.SelectedItem; //选择转换的格式.
            switch(formatSelected) {
                case "*.jpeg":
                    nFormat = 0;
                    break;


                case "*.gif":
                    nFormat = 1;
                    break;
                case "*.bmp":
                    nFormat = 2;
                    break;
                case "*.png":
                    nFormat = 3;
                    break;
                default:
                    throw new ArgumentException("不支持的转换格式");
            }
            new Thread(new ThreadStart(ConvertImage)).Start();  //用多线程启动.
        }

        //图片转换方法.
        void ConvertImage() {
            int nSchedule = 0;   //进度值.
            switch(nFormat) { //用两次switch是为了用多线程.
                case 0:
                    for(int i = 0; i < picNames.Length; i++) {
                        using(bMap = new Bitmap(picNames[i])) {
                            bMap.Save(strSavePath + "\" + Path.GetFileNameWithoutExtension(picNames[i]) + ".jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);


                            lv.Items[nSchedule].SubItems[6].Text = "已转换";
                            nSchedule++;
                            ts_status_lab.Text = string.Format("已完成 {0} %", i * 100 / picNames.Length);
                        }
                    }
                    break;
                case 1:
                    for(int i = 0; i < picNames.Length; i++) {
                        using(bMap = new Bitmap(picNames[i])) {
                            bMap.Save(strSavePath + "\" + Path.GetFileNameWithoutExtension(picNames[i]) + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                            lv.Items[nSchedule].SubItems[6].Text = "已转换";
                            nSchedule++;
                            ts_status_lab.Text = string.Format("已完成 {0} %", i * 100 / picNames.Length);
                        }
                    }
                    break;


                case 2:
                    for(int i = 0; i < picNames.Length; i++) {
                        using( bMap = new Bitmap(picNames[i])) {
                            bMap.Save(strSavePath + "\" + Path.GetFileNameWithoutExtension(picNames[i]) + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
                            lv.Items[nSchedule].SubItems[6].Text = "已转换";
                            nSchedule++;
                            ts_status_lab.Text = string.Format("已完成 {0} %", i * 100 / picNames.Length);
                        }
                    }
                    break;
                case 3:
                    for(int i = 0; i < picNames.Length; i++) {
                        using( bMap = new Bitmap(picNames[i])) {
                            bMap.Save(strSavePath + "\" + Path.GetFileNameWithoutExtension(picNames[i]) + ".png", System.Drawing.Imaging.ImageFormat.Png);
                            lv.Items[nSchedule].SubItems[6].Text = "已转换";


                            nSchedule++;
                            ts_status_lab.Text = string.Format("已完成 {0} %", i * 100 / picNames.Length);
                        }
                    }
                    break;
                default:
                    throw new ArgumentException("未知的参数");
            }
            if(nSchedule == picNames.Length)    //此时表示完成转换.
                ts_status_lab.Text = "转换已全部完成";
        }
    }
}


[解决办法]
  怎么了? 这是一段实用代码吧,谢谢分享
[解决办法]
lv是界面上的一个控件吧
控件只能在事件线程上调用
你这么写: this.Invoke(new Action(()=>{//do sth...}))
[解决办法]
控件只能在创建该控件的线程上操作,这是.NET的一个安全机制。
要想使用异步线程来修改控件的状态,可以使用Control.BeginInvoke方法,
或者设置CheckForIllegalCrossThreadCalls属性。
推荐使用前者。

热点排行