• 一款垃圾的仿资源管理器+局域网Ping网段的工具(winform+异步线程) 留了问题


    闲来无事,这几天学习了线程,想在winfom里调用 异步委托来实现。好多需求都没有完成,哎。。。

    第一个是:仿资源管理器

    问题:如何实现 双击击 listView 打开目录,关键点是:我不会获取 listView选中项目的路径

    代码如下:

    View Code
    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;
    using System.Runtime.Remoting.Messaging;
    using System.Diagnostics;

    namespace 资源管理器
    {
    //声明委托
    public delegate void DeleMethod(string[] dirs);
    public delegate void DeleMethod2(TreeNode node);

    public partial class explorer : Form
    {
    public explorer()
    {
    InitializeComponent();
    }
    TreeNode parent;
    private void explorer_Load(object sender, EventArgs e)
    {
    parent = treeView1.Nodes.Add("我的电脑");
    GetDrive(parent);
    listView1.LargeImageList = imageList1;
    }
    /*
    *
    *
    *
    * 方法
    *
    *
    */
    //获取磁盘
    private void GetDrive(TreeNode parent)
    {

    string[] drives = Directory.GetLogicalDrives();
    foreach (var drive in drives)
    {
    parent.Nodes.Add(drive);
    }
    }

    //获取某磁盘的目录(文件夹)
    private void GetDir(TreeNode oneNode)
    {
    DeleMethod dele = ListShow;
    DeleMethod dele2 = ListViewShow;
    DeleMethod2 dele3 = PicShow;

    string[] dirs = Directory.GetDirectories(oneNode.Text);
    //异步线程1
    dele.BeginInvoke(dirs, null, null);
    //异步线程2
    dele2.BeginInvoke(dirs, null, null);
    //异步线程3
    dele3.BeginInvoke(oneNode, null, null);
    //主线程
    foreach (var n in dirs)
    {
    oneNode.Nodes.Add(n);
    }

    }

    //显示在ListBox
    private void ListShow(string[] dirs)
    {
    listBox1.Items.Add("当前线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString());
    foreach (var n in dirs)
    {
    listBox1.Items.Add(n);

    }
    }

    //显示在ListView
    private void ListViewShow(string[] dirs)
    {
    foreach (var n in dirs)
    {
    string name = Path.GetFileName(n);
    listView1.Items.Add(name);
    }
    }

    //显示图标
    private void PicShow(TreeNode node)
    {
    for (int i = 0; i < node.Nodes.Count; i++)
    {
    listView1.Items[i].ImageIndex = 0;
    }
    }
    //打开文件夹
    private void OpenDir(string path)
    {
    Process.Start("explorer.exe", path);
    }
    /*
    *
    *
    *
    * 事件
    *
    *
    */

    //单击Node节点事件
    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
    {
    listBox1.Items.Clear();
    listView1.Items.Clear();
    if (e.Node.Parent == null)
    {
    return;
    }

    else
    {
    //改善异常操作对用户的界面体验
    try
    {
    GetDir(e.Node);
    }
    catch (Exception m)
    {
    MessageBox.Show("请将磁盘插入驱动器(DVD):", "插入磁盘", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
    }


    }
    //实现ListView双击打开目录
    private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
    MessageBox.Show("********未实现********");


    }

    //实现ListBox双击打开目录
    private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
    if (listBox1.SelectedItems.Count != 1)//防止多选,在Load加载listView1.MultiSelect = false;也可以
    {
    return;
    }
    else
    {
    string path = listBox1.SelectedItem.ToString();
    string[] temp = Directory.GetFileSystemEntries(path);
    listBox1.Items.Clear();
    foreach (var n in temp)
    {
    listBox1.Items.Add(n);
    }
    }
    }
    }
    }

    第二个是:局域网Ping 整个网段的工具

    以前写过一个,但是,那个效率。。。实在是。。。这次加入了异步委托,实现了 异步线程执行,效率大大提高了。

    代码如下:

    View Code
    PING局域网存活PC(线程版)
    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.Diagnostics;
    using System.Threading;
    using System.Runtime.Remoting.Messaging;



    namespace WindowsFormsApplication6
    {
    public delegate string DeleMethod(string ip,int i);
    public partial class Form1 : Form
    {

    public Form1()
    {
    InitializeComponent();



    }


    private void Form1_Load(object sender, EventArgs e)
    {

    label1.Text = DateTime.Now.ToLocalTime().ToString();//加载的时候就显示时间
    //实时更新
    timer1.Enabled = true;
    timer1.Interval = 1000;

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    label1.Text = DateTime.Now.ToLocalTime().ToString() ;
    }

    private void button1_Click(object sender, EventArgs e)
    {
    listBox1.Items.Clear();
    //判断正确的输入格式
    if (textBox1.Text == string.Empty || textBox2.Text == string.Empty)
    {

    MessageBox.Show("IP地址不为空", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }
    else
    {
    if (textBox2.Text.Length > 3 | textBox2.Text.Length<=0)
    {
    MessageBox.Show("第二组IP有误", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }

    else if (int.Parse(textBox2.Text) == 255 || int.Parse(textBox2.Text) == 0)
    {
    MessageBox.Show("第二组IP为广播地址", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }
    else
    {
    string[] ips = textBox1.Text.Split('.');
    if (ips.Length != 4)//因为IP是4段
    {

    MessageBox.Show("第一组IP有误", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }
    if (int.Parse(ips[3]) == 0 || int.Parse(ips[3]) == 255)
    {
    MessageBox.Show("第一组IP为广播地址", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }

    int i1=int.Parse(ips[3]);
    int i2=int.Parse(textBox2.Text);
    if(i1>i2)
    {
    MessageBox.Show("后面IP太小", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    return;
    }

    DeleMethod delemethod = Ping;
    AsyncCallback callBack = new AsyncCallback(callMethod);
    for (int i = i1; i <= i2; i++)
    {

    delemethod.BeginInvoke(i.ToString(),i,callBack,null);


    }
    }
    }

    }
    //回调函数
    private void callMethod(IAsyncResult ar)
    {
    AsyncResult result = (AsyncResult)ar;
    DeleMethod dele = (DeleMethod)result.AsyncDelegate;
    string temp=dele.EndInvoke(ar);
    listBox1.Items.Add(temp);
    }
    private string Ping(string ip,int i)//调用Ping方法
    {
    string temp;
    Process p = new Process();
    p.StartInfo.FileName = "cmd.exe";//获取程序的事件 注意FileName包含路径
    p.StartInfo.UseShellExecute = false;
    //重定向 标准输出 输入 错误
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.CreateNoWindow = true;//不显示窗口
    p.Start();
    p.StandardInput.WriteLine(string.Format("ping -n 1 192.168.0.{0}",ip));
    p.StandardInput.WriteLine("exit");
    temp=p.StandardOutput.ReadToEnd();
    if (temp.Contains("Received = 1"))
    {

    return string.Format("ID:"+Thread.CurrentThread.ManagedThreadId+"\n"+"提示:192.168.0.{0}存在", i);
    }
    else
    {

    return string.Format("ID:" + Thread.CurrentThread.ManagedThreadId + "\n" + "提示:192.168.0.{0}可能不存在", i);
    }

    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
    DialogResult result=MessageBox.Show("是否要关闭软件","提示",MessageBoxButtons.YesNo,MessageBoxIcon.Warning);

    if (result == DialogResult.Yes)
    {
    e.Cancel =false;//这是一个关闭事件,不取消事件,也就是不关闭
    }
    else
    {
    e.Cancel = true;//这是一个关闭事件,取消事件,就是关闭
    }
    }

    private void richTextBox1_TextChanged(object sender, EventArgs e)
    {

    }
    }
    }

    总结:

    1.winform中 调用异步委托 不是我们 想象的那么简单。

    2.

    问题:大家都知道MessageBoxButtons的枚举值,是显示 确认 取消的,这是一个枚举,但是我今天想找一个 “只显示 取消”按钮的,居然没找到,所有我想增加 枚举值,不知道如何做?

    求给思路。

    3.

    对异步线程的总结:

    异步线程:不管你是否使用EndInvoke();在winform中 都不会影响 你的”显示结果“,这里是显示结果,而不是返回值。

    这里的返回值是指 委托方法的返回值。

    对于异步委托,线程执行结束之后,会回到线程池。

    问题:

    对于 Thread类新建的线程,执行完后,如何销毁呢?

    4.问题:如何实现 双击击 listView 打开目录,关键点是:我不会获取 listView选中项目的路径

  • 相关阅读:
    insert插入多条数据
    dbms_output输出中文乱码
    redhat6.2安装rlwrap
    IIS实现HTTPS的主机名绑定
    windows10家庭版 远程桌面报错
    Encryption requires the OpenSSL PHP extension 报错
    Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use ...报错
    报错:org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
    异常:java.lang.NoClassDefFoundError: org/springframework/expression/ParserContext
    IntelliJ Idea解决Could not autowire. No beans of 'xxxx' type found的错误提示
  • 原文地址:https://www.cnblogs.com/IAmBetter/p/2346589.html
Copyright © 2020-2023  润新知