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

推荐订阅源

S
SegmentFault 最新的问题
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
量子位
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
GbyAI
GbyAI
爱范儿
爱范儿
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
罗磊的独立博客
Recent Announcements
Recent Announcements
博客园 - 司徒正美
M
MIT News - Artificial intelligence
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog RSS Feed
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
雷峰网
雷峰网

博客园 - 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中报错。