C# Winform 界面操作异步回调 AsyncCallback_C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            m_DebugActionDic = new Dictionary<object, Func<bool>>();
        }

        private Dictionary<object, Func<bool>> m_DebugActionDic;
        private string m_ErrorMessage;
        private void ResultCallBack(IAsyncResult res)
        {
            Control ctrl = res.AsyncState as Control;
            ctrl.Invoke(new Action(() => ctrl.Enabled = true));

            if (!m_DebugActionDic[res.AsyncState].EndInvoke(res))
            {
                MessageBox.Show(m_ErrorMessage);
            }

            m_DebugActionDic.Remove(res.AsyncState);
        }

        private bool Button1Action()
        {
            try
            {
                int floor = int.Parse(textBox1.Text);
                Thread.Sleep(3000);

                return true;
            }
            catch (Exception ex)
            {
                m_ErrorMessage = ex.Message;
                return false;
            }
        }

        private bool Button2Action()
        {
            try
            {
                int floor = int.Parse(textBox2.Text);
                Thread.Sleep(3000);

                return true;
            }
            catch (Exception ex)
            {
                m_ErrorMessage = ex.Message;
                return false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Control ctrl = sender as Control;
            ctrl.Enabled = false;
            m_DebugActionDic.Add(sender, new Func<bool>(Button1Action));
            m_DebugActionDic[sender].BeginInvoke(ResultCallBack, sender);
        }

        private void button2_Click(object sender, EventArgs e) // Button 时间可以都关联一个就可以了
        {
            Control ctrl = sender as Control;
            ctrl.Enabled = false;
            m_DebugActionDic.Add(sender, new Func<bool>(Button2Action));
            m_DebugActionDic[sender].BeginInvoke(ResultCallBack, sender);
        }
    }
}





封装一下,方便其他地方调用。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form, IResultCallBack
    {
        public Form1()
        {
            InitializeComponent();
            m_UICallBackFunc = new UICallBackFunc();
        }

        private readonly UICallBackFunc m_UICallBackFunc;

        private string m_ErrorMessage;
        public void ResultCallBack(IAsyncResult res)
        {
            if (!m_UICallBackFunc.GetFunc(res.AsyncState).EndInvoke(res))
            {
                MessageBox.Show(m_ErrorMessage);
            }

            m_UICallBackFunc.ResultCallBack(res);
        }

        private bool Button1Action()
        {
            try
            {
                int floor = int.Parse(textBox1.Text);
                Thread.Sleep(3000);

                return true;
            }
            catch (Exception ex)
            {
                m_ErrorMessage = ex.Message;
                return false;
            }
        }

        private bool Button2Action()
        {
            try
            {
                int floor = int.Parse(textBox2.Text);
                Thread.Sleep(5000);

                return true;
            }
            catch (Exception ex)
            {
                m_ErrorMessage = ex.Message;
                return false;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            m_UICallBackFunc.BindCallBack(sender, Button1Action, ResultCallBack);
        }

        private void button2_Click(object sender, EventArgs e) // Button 时间可以都关联一个就可以了
        {
            m_UICallBackFunc.BindCallBack(sender, Button2Action, ResultCallBack);
        }
    }

    public class UICallBackFunc : IResultCallBack
    {
        public UICallBackFunc()
        {
            m_DebugActionDic = new Dictionary<object, Func<bool>>();
        }

        protected readonly Dictionary<object, Func<bool>> m_DebugActionDic;

        public void BindCallBack(object sender, Func<bool> func, AsyncCallback callback)
        {
            if (m_DebugActionDic.ContainsKey(sender))
            {
                return; // 异步过程还没执行完成直接返回
            }

            Control ctrl = sender as Control;
            ctrl.Enabled = false;
            m_DebugActionDic.Add(sender, new Func<bool>(func));
            m_DebugActionDic[sender].BeginInvoke(callback, sender);
        }

        public Func<bool> GetFunc(object sender)
        {
            return m_DebugActionDic[sender];
        }

        protected void RemoveFunc(object sender)  // 在回调函数中调用清除
        {
            if (m_DebugActionDic.ContainsKey(sender))
            {
                m_DebugActionDic.Remove(sender);
            }
        }

        public void ResultCallBack(IAsyncResult res)
        {
            Control ctrl = res.AsyncState as Control;
            ctrl.Invoke(new Action(() => ctrl.Enabled = true));
            RemoveFunc(res.AsyncState);
        }
    }

    public interface IResultCallBack
    {
        void ResultCallBack(IAsyncResult res);
    } // end interface
}





直接这样子:

public class UICallBackFunc
{
    public UICallBackFunc()
    {
        m_DebugActionDic = new Dictionary<object, Func<bool>>();
        m_FuncDoneDic = new Dictionary<object, Action<bool>>();
    }

    protected readonly Dictionary<object, Func<bool>> m_DebugActionDic;
    protected readonly Dictionary<object, Action<bool>> m_FuncDoneDic; // 执行完后,传过来的结果

    public void BindCallBack(object sender, Func<bool> func, Action<bool> funcDone)
    {
        if (m_DebugActionDic.ContainsKey(sender))
        {
            return; // 异步过程还没执行完成直接返回
        }

        m_FuncDoneDic.Add(sender, funcDone);
        Control ctrl = sender as Control;
        ctrl.Enabled = false;
        m_DebugActionDic.Add(sender, new Func<bool>(func));
        m_DebugActionDic[sender].BeginInvoke(ResultCallBack, sender);
    }

    protected void ResultCallBack(IAsyncResult res)
    {
        Control ctrl = res.AsyncState as Control;
        ctrl.Invoke(new Action(() => ctrl.Enabled = true));
        m_FuncDoneDic[res.AsyncState].Invoke(m_DebugActionDic[res.AsyncState].EndInvoke(res));
        m_DebugActionDic.Remove(res.AsyncState);
        m_FuncDoneDic.Remove(res.AsyncState);
    }
}