zoukankan      html  css  js  c++  java
  • 异步调用之精简方式

    不知道在Winform代码中,你是否遇到过线程和UI交互的情况?然后你是不是都是按照这种方式来书写代码的:

    public delegate void AddListViewCrossThreadDelegate(******);

    public void AddListViewCrossThreads(ListViewItem lvi,int action)
    {
    if (lsvName.InvokeRequired)
    {
    AddListViewCrossThreadDelegate d = new AddListViewCrossThreadDelegate(AddListViewCrossThreads);
    lsvName.Invoke(addlistviewdelegate, lvi,action);
    }
    else
    {
    //这里添加实际操作控件的代码

    }
    }

    但是如果当一个页面中有大量的控件要涉及到UI交互,并且这些控件需要好多不同的参数,那么我们就不得不为这些控件声明具有不同参数的委托类型,然后再利用InvokeRequired来判断,最后编写世纪操控控件的代码。如果真是这样,那么这个工作量可真的是很大。并且这种Copy/Paste的工作可能让你发疯,重用性太差了,有没有好一点的方法呢?当然有:

    通过观察发现,每个控件在进行线程和UI交互的时候,都需要判断以下是否需要进行线程交互(也就是判断是否需要InvokeRequired),那么这个操作能不能集成到一个类中完成呢?看代码:

    using System.Windows.Forms;

    namespace CommonUntil
    {
    public static class UIThread
    {
    public static void UIInvoke(this Control control, MethodInvoker invoker)
    {
    if (control.InvokeRequired) //如果产生了线程和界面的交互
    {
    control.Invoke(invoker); //利用MethodInvoker可以代替任意Delegate的方法
    return;
    }
    else
    {
    invoker.Invoke(); //触发交互事件
    }
    }
    }
    }

    那么,应该怎么使用呢?

    假设我们需要望名称为lsvName的ListView控件中添加新的ListViewItem对象,并且我们规定,传入addFlag就表明是添加列表项,传入deleteFlag就是清空所有选项,我们会这么操作:

         public void AddListView(ListViewItem lvi,int action)
    {
    if (addFlag == action)
    {
    this.lsvName.Items.Add(lvi);
    }
    else if (deleteFlag == action)
    {
    this.lsvName.Items.Clear();
    }
    }

    如果在遇到线程交互的时候,我们该怎么做呢?我们只需要获取到ListViewItem对象和action,就可以通过我们实现的扩展方法来实现:

            for (int i = 0; i < myFiles.Count; i++)
    {
    FileInfo file = myFiles[i];
    ListViewItem lvi = new ListViewItem();
    lvi.Text = GetFileName.GetFileName(file.FullName);
    lvi.Tag = file.FullName; // store the fullname

    UIThread.UIInvoke(lsvName,
    delegate
    {
    AddListView(lvi, addFlag);
    }
    );
    }

    或者直接干脆的这么写:

     UIThread.UIInvoke(lsvName,
    delegate
    {
    //AddListView(lvi, action);
    if (addFlag == action)
    {
    this.lsvName.Items.Add(lvi);
    }
    else if (deleteFlag == action)
    {
    this.lsvName.Items.Clear();
    }
    }
    );

     这样,我们就不必对不同的参数每次都赋值进去,然后判断在操控,代码也简洁了许多,希望对你有用。


     



     

  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/scy251147/p/2262124.html
Copyright © 2011-2022 走看看