Skip to content
标签
欢迎扫码关注公众号

使用 Delegate 实现 APM(异步委托编程模型)

使用 delegateBeginInvokeEndInvoke 实现异步;

使用 SynchronizationContext 实现跨线程访问控件;

示例代码

cs
using System;
using System.IO;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace APMSampleUseDelegate
{
    public partial class MainForm : Form
    {
        private delegate void AsyncMethodCaller(string url);
        SynchronizationContext sc;

        public MainForm()
        {
            InitializeComponent();
            txtUrl.Text = "http://www.baidu.com/";
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            btnDownload.Enabled = false;
            if (txtUrl.Text == string.Empty)
            {
                MessageBox.Show("Please input valid download file url");
                btnDownload.Enabled = true;
                return;
            }
            txtUrlHtml.Text = string.Empty;

            AsyncMethodCaller caller = new AsyncMethodCaller(DownloadHtml);
            caller.BeginInvoke(txtUrl.Text, GetResult, null);

            sc = SynchronizationContext.Current;
        }

        private void DownloadHtml(string url)
        {
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;

            Stream responseStream = response.GetResponseStream();
            byte bufferRead = new byte[1000];
            int pageSize = responseStream.Read(bufferRead, 0, bufferRead.Length);
            while (pageSize > 0)
            {
                sc.Post(ShowPageHtml, Encoding.UTF8.GetString(bufferRead));
                bufferRead = new byte[1000];
                pageSize = responseStream.Read(bufferRead, 0, bufferRead.Length);
                //Thread.Sleep(300);
            }
        }

        // 异步操作完成时执行的方法
        private void GetResult(IAsyncResult ar)
        {
            AsyncMethodCaller caller = (ar as AsyncResult).AsyncDelegate as AsyncMethodCaller;
            // 调用 EndInvoke 去等待异步调用完成并且获得返回值
            // 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成
            caller.EndInvoke(ar);
            // 通过获得 GUI 线程的同步上下文的派生对象,
            // 然后调用 Post 方法来使更新 GUI 操作方法由 GUI 线程去执行
            sc.Post(ResetBtnState, null);
        }

        private void ShowPageHtml(object result)
        {
            txtUrlHtml.Text += result.ToString();
        }

        private void ResetBtnState(object state)
        {
            btnDownload.Enabled = true;
        }
    }
}

参考

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.