天天看點

async+await 讓界面飛,讓雙手爽

.net 4.5已經釋出很久了,但是一直也沒有靜下心來好好的研究微軟給開發者帶來的喜悅。

今天我将簡單的介紹下 async + await 這對搭檔的出現,如何讓頻繁假死的界面飛起來(其實隻是不再阻塞UI線程而已,标題黨一下)

建議大家先了解下 IAsyncReuslt ,做過異步的應該都知道它怎麼用吧?用過socket的人也幾乎對它了如指掌了,不知道的谷歌一下吧,我就不貼上來了。

  • async + await 讓界面飛

   園子裡“滴答的雨”已經詳細解釋過了,我這裡隻貼一個例子以便跟我寫的方式進行對比。

   其中 for 循環是為了增加網絡延遲,模拟一定的加載時間而已,網速好的同學可以自行放寬。

  

private async void button1_Click(object sender, EventArgs e)
        {
            string s = await Test();
            MessageBox.Show(s);
        }

        private async Task<string> Test()
        {
            string str = null;

            for (int i = 0; i < 10; i++)
            {
                using (WebClient wc = new WebClient())
                {
                    str = await wc.DownloadStringTaskAsync("http://www.baidu.com");
                }
            }

            return str;
        }      
  • 讓雙手爽,讓代碼簡潔,讓假死瞬間複活

   現在我想讓我的代碼變成這個樣子,盡量少的改動之前的函數,同時新寫的方法也不需要考慮傳回Task<T>

其實差別在于兩點:

    1. await new FastAsync<string>().TaskAsync();

    2.TestAsync 函數本身沒有引用到 async 或者 await ,也就是說邏輯函數相比較之前的版本來說沒有做出改動。

private async void button1_Click(object sender, EventArgs e)
        {
            string s = await new FastAsync<string>().TaskAsync(TestAsync);
            MessageBox.Show(s);
        }

        private string TestAsync()
        {
            string str = null;

            for (int i = 0; i < 10; i++)
            {
                using (WebClient wc = new WebClient())
                {
                    str = wc.DownloadString("http://www.baidu.com");
                }
            }

            return str;
        }      
  • 改造async + await的使用方式,提供快速操作函數

   通過上面的代碼應該已經發現問題了,就是 FastAsync<string> 是哪裡來的呢?這就是今天要說的重點了。代碼量不多,隻沒特别的技術含量隻是需要動下腦而已。

public class FastAsync<T>
    {
        TaskCompletionSource<T> m_tcs;

        public Task<T> TaskAsync(Func<T> func)
        {
            m_tcs = new TaskCompletionSource<T>();
            IAsyncResult result = func.BeginInvoke(new AsyncCallback(AsyncResult), func);

            return m_tcs.Task;
        }

        private void AsyncResult(IAsyncResult result)
        {
            Func<T> func = result.AsyncState as Func<T>;
            T entity = func.EndInvoke(result);
            m_tcs.SetResult(entity);
        }
    }      

   是不是很簡單?

   或許大家有更好的方法,歡迎交流,本文的實作方式隻是我一時興起想出來的,目的也很簡單,就是想簡化代碼。

   當然,這也未必是最簡單的實作方式,在這裡我隻能說我提供的是一個思路,一個簡化版實作方式而已,真實項目中還要繼續改進和擴充。如果您喜歡,麻煩點個贊?哈哈^_^

自動簽名

歡迎加入技術交流群:

async+await 讓界面飛,讓雙手爽
招.Net中/進階開發工程師:坐标杭州下沙,聯系方式進群找群主,薪資範圍16-30K,有住房補貼