2013-09-26 26 views
0

我是新來的使用回調和異步函數,所以我有點不確定最好的方法來處理這個問題。將回調值返回到啓動異步方法的函數的最佳方法是什麼?

我創建了一個名爲SendPhoto()的函數,該函數被我的GUI調用。 SendPhoto()函數與我的GUI不在一個類中。用來調用WebClient.UploadFile()

public string SendPhoto(string filename) 
    { 
     byte[] response = PostFile(_url, filename); 

     String responsestring = Encoding.ASCII.GetString(response); 

     if (responsestring.StartsWith("ERROR:")) 
      return responsestring; 
     else if (responsestring.Contains("<valid>1</valid>")) 
      return "OK"; 
     else 
      return responsestring; 
    } 

PostFile()功能,並且響應返回給SendPhoto(),和它的工作很大。然後我決定我想要異步發送照片,所以在我的PostFile()功能中,我將呼叫從Uploadfile()更改爲UploadFileAsync()

但是,我意識到UploadFileAsync()沒有返回值,我必須使用UploadFileCompletedEventHandler完成上傳時才能獲得響應。所以,我在與SendPhoto()PostFile()相同的類中編寫了一個回調函數來檢索響應,在該函數上實例化UploadFileCompletedEventHandler,並將其傳遞到我的PostFile()函數中。

問題是,我不知道如何獲得響應回SendPhoto()函數,以便它可以解釋響應並將友好的響應發送回GUI。之前,當所有內容都是同步的時候,響應只是傳回備份堆棧,但現在,響應消失了幾層。

什麼是從回調函數返回回覆到SendPhoto()的最佳方式,現在PostFile()不能再返回給我了?我想將事件處理函數回調移動到GUI並將UploadFileCompletedEventHandler傳遞給SendPhoto(),然後將它發送到PostFile()。但我試圖在GUI類中保留「業務邏輯」(即解釋響應)。

+1

您可以嘗試異步等待。你有沒有嘗試過'WebClient.UploadFileTaskAsync'方法。這會返回一個您可以等待的「任務」?這些是最新的功能。 – Muctadir

回答

1

好吧,今天早上再做一些工作,使用「await」(謝謝Muctadir Dinar!)發現了一個非常優雅的解決方案。我必須將我的調用更改爲UploadFileTaskAsync(),以便它支持「await」關鍵字,並且必須使用「async」修飾所有方法,並讓它們返回任務,一直返回到GUI按鈕點擊事件處理程序,但是當我完成時,它運行得非常好!我相信這隻會在.NET框架4.5中起作用。

private async void UploadPhotoButton_Click(object sender, EventArgs e) 
    { 
     ... 
     string theResult = await MyProvider.SendPhotoAsync(pathToFile, new UploadProgressChangedEventHandler(UploadProgressCallback)); 
     OutputBox.Text = theResult; 
    } 

    public async Task<string> SendPhotoAsync(string filename, UploadProgressChangedEventHandler changedHandler) 
    { 
     byte[] response = await PostFileAsync(_url, filename, changedHandler); 

     String responsestring = Encoding.ASCII.GetString(response); 

     if (responsestring.StartsWith("ERROR:")) 
      return responsestring; 
     else if (responsestring.Contains("<valid>1</valid>")) 
      return "OK"; 
     else 
      return responsestring; 
    } 

    async Task<byte[]> PostFileAsync(string uri, string filename, UploadProgressChangedEventHandler changedHandler) 
    { 
     byte[] response = null; 
     using (WebClient client = new WebClient()) 
     { 
      client.Headers = GetAuthenticationHeader(); 
      client.UploadProgressChanged += changedHandler; 

      response = await client.UploadFileTaskAsync(new Uri(uri), filename); 
     } 

     return response; 
    } 
相關問題