惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
A
About on SuperTechFans
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Latest
Security Latest
Project Zero
Project Zero
A
Arctic Wolf
L
LINUX DO - 热门话题
Microsoft Azure Blog
Microsoft Azure Blog
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cloudbric
Cloudbric
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
T
Threatpost
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
PCI Perspectives
PCI Perspectives
WordPress大学
WordPress大学
T
Tor Project blog
阮一峰的网络日志
阮一峰的网络日志
The Hacker News
The Hacker News
V
Visual Studio Blog
M
MIT News - Artificial intelligence
月光博客
月光博客
D
DataBreaches.Net
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Simon Willison's Weblog
Simon Willison's Weblog
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
MyScale Blog
MyScale Blog
N
Netflix TechBlog - Medium
S
Security Affairs
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
AI
AI
S
Schneier on Security
L
LangChain Blog
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 叶小钗
量子位
H
Heimdal Security Blog
J
Java Code Geeks

博客园 - Animax!

The Tao of Programming Light weight Framework (AnyBase) -- 通信模块说明 关于WinIO.DLL的键盘输入模拟 Light weight Framework (AnyBase) -- Core 模块说明 开源项目 Light weight Framework (AnyBase) 发布 DB4o的缓存机制 db4o 研究--性能测试 Asp.net动态数据(Dynamic Data) 笔记一 MVC — 笔记 WF笔记 – Workflow概念 WCF Demo – Http、TCP Host - Animax! LINQ TO SQL 笔记 — 存储过程、并发与事务 WCF笔记 - 绑定 WCF 笔记 正则表达式[转载整理] - Animax! - 博客园 LINQ 笔记 - LINQ to SQL 基本数据操作 - Animax! LINQ 笔记 - 语法与关键字 LINQ 笔记- Lambda Excel导入SQL - Animax! - 博客园
Winfrom界面异步操作的一个解决方法
Animax! · 2009-07-21 · via 博客园 - Animax!

2009-07-21 21:44  Animax!  阅读(2621)  评论()    收藏  举报

首先定义为界面需要两个部分:

1、界面的逻辑操作部分
2、界面显示部分


基本思路如下:
界面逻辑操作部分提供支持方法以及支持方法列表。
界面显示部分主动触发逻辑操作,并把操作完成后界面操作内容封装为一个闭包传入逻辑操作部分。
界面逻辑操作在每次操作完成后激发界面显示部分闭包的操作内容。

下面就定义一个界面逻辑操作的基类来处理异步的操作:


    public class ViewOperation

    {

        private class ActionEventState

        {

            public ActionEventState()

            {

                IsEndInvoke = false;

            }

            public Guid EventID { getset; }

            public Control View { getset; }

            public LogicActionHandler handler { getset; }

            public object CallBackValue { getset; }

            public bool IsEndInvoke { getset; }

        }

        protected delegate object LogicActionHandler(object data);

        public delegate void ActionCallBack(object ActionState);

        protected Dictionary<stringLogicActionHandler> ActionHandlerList = new Dictionary<stringLogicActionHandler>();

        private Dictionary<GuidActionCallBack> _actionCallBackList = new Dictionary<GuidActionCallBack>();

        /// <summary>

        /// 异步操作执行

        /// </summary>

        public void DoAction(Control view, string ActionKey, object Data, ActionCallBack callBack)

        {

            Guid EventID = Guid.NewGuid();

            _actionCallBackList.Add(EventID, callBack);

            if (ActionHandlerList.ContainsKey(ActionKey))

            {

                LogicActionHandler handler = ActionHandlerList[ActionKey];

                var i = handler.BeginInvoke(Data, ActionCallback, new ActionEventState() { EventID = EventID, View = view, handler = handler });

            }

        }

        private void ActionCallback(IAsyncResult ar)

        {

            ActionEventState state = (ActionEventState)ar.AsyncState;

            if (!state.IsEndInvoke)

            {

                object callBackValue = state.handler.EndInvoke(ar);

                state.CallBackValue = callBackValue;

                state.IsEndInvoke = true;

            }

            if (state.View.InvokeRequired)

            {

                state.View.Invoke(new AsyncCallback(ActionCallback), new object[] { ar });

            }

            else

            {

                // 回调

                if (_actionCallBackList.ContainsKey(state.EventID))

                {

                    try

                    {

                        if (_actionCallBackList[state.EventID] != null)

                            _actionCallBackList[state.EventID](state.CallBackValue);

                    }

                    catch (Exception ex)

                    {

                        // TODO : 错误处理

                    }

                    finally

                    {

                        _actionCallBackList.Remove(state.EventID);

                    }

                }

            }

        }

}

使用Demo

逻辑操作的类,需要注册它所拥有的方法:

    public class Viewlogic : ViewOperation

    {

        public Viewlogic()

        {

            base.ActionHandlerList.Add("SomeOperation"new LogicActionHandler(SomeOperation));

        }

        private object SomeOperation(object data)

        {

            Thread.Sleep(Convert.ToInt32(data.GetType().GetProperty("waitTime").GetValue(data, null)));

            return data.GetType().GetProperty("Msg").GetValue(data, null).ToString();

        }

    }

界面调用,按照方法的Key调用改方法:

     new Viewlogic().DoAction(this"SomeOperation",

         new

         {

             waitTime = 2000,

             Msg = "viewMsg"

         },

         new ViewOperation.ActionCallBack(o =>

             {

                 MessageBox.Show(o.ToString());

             }));

这个方法的缺点:

界面和逻辑数据传递就依靠一个object,界面需要知道传入的数据和放回的数据。

界面需要知道能调用的方法。这个虽然是在一个列表中,可以在逻辑类中列出他拥有的方法,但是在开发时没有环境支持。

> 在回调过程中界面出现错误,VS是会在ViewOperation中报错。