2014-03-24 32 views
0

我有一個MVC 4應用程序。它的一個做的事情就是通過調用使用WebClient像這樣其他服務發送電子郵件:如何等待一個字節[]

var serializer = new JavaScriptSerializer(); 
string requestData = serializer.Serialize(new 
{ 
    EventID = 1, 
    SubscriberID = studentId, 
    ToList = loginModel.EmailAddress, 
    TemplateParamVals = strStudentDetails, 
}); 

using (var client = new WebClient()) 
{ 
    client.Headers[HttpRequestHeader.ContentType] = "application/json"; 
    var result = await client.UploadData(URI, Encoding.UTF8.GetBytes(requestData)); 
} 

我想利用UploadDataAsync但得到的錯誤:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle.

於是我想到的創建一個包裝函數&使它異步同時仍然使用UploadDataAsync

private async Task<bool> SendEmailAsync(long studentId, LoginModel loginModel) 
{ 
    try 
    { 
     string URI = ConfigurationManager.AppSettings["CommunicationmanagerURL"] + "PostUserEvent"; 
     var serializer = new JavaScriptSerializer(); 

     string requestData = serializer.Serialize(new 
     { 
      EventID = 1, 
      SubscriberID = studentId, 
      ToList = loginModel.EmailAddress, 
      TemplateParamVals = strStudentDetails, 
     }); 

     using (var client = new WebClient()) 
     { 
      client.Headers[HttpRequestHeader.ContentType] = "application/json"; 
      var result = await client.UploadData(URI, Encoding.UTF8.GetBytes(requestData));  
     } 
    } 
    catch (Exception ex) 
    { 
     // Log exceptions ... 
    } 
} 

這不建,並給出了錯誤:

Cannot await 'byte[]'

任何想法如何解決這個問題?

+0

我有一種感覺,當你嘗試打電話給你的包裝時,你仍然會遇到問題。 – Rawling

回答

1

你不能等待一個等時線功能,您必須調用[..]異步之一:

var result = await client.UploadDataAsync(URI, Encoding.UTF8.GetBytes(requestData)); 

你調用返回byte[]的功能,這當然是不awaitable。 UploadDataAsync返回Task<byte[]>相反,這一次你要使用:

http://msdn.microsoft.com/de-de/library/ms144225(v=vs.110).aspx

編輯: 的方法似乎返回void,這是一種awaitable,太..在發射後不管的條款。

+1

UploadDataAsync方法不返回任務,它使用UploadDataCompleted事件。改用UploadDataTaskAsync。 –

+0

你是對的,我在此期間編輯了我的答案。我不會再編輯我的答案,而是讚揚你的。 – Herm

0

您在示例代碼中使用的UploadData方法是同步操作。正如編譯器所說的,你不能等待同步操作。問題不是byte[]類型,而是操作本身。

如果要使用await,則需要使用異步操作。 WebClient提供UploadData方法的兩個異步版本:

正常使用的await functionnality,你需要使用UploadDataTaskAsync

編輯:我的第一個答案是關於你從編譯器得到的警告。你所要做的就是將調用包裝到一個任務中的同步操作中,使其成爲異步。

您可以通過創建自己的Task並返回其實現這一目標:

private async Task<bool> SendEmailAsync(long studentId, LoginModel loginModel) 
{ 
    Task<bool> uploadTask = Task.Factory.StartNew<bool>(
     () => 
     { 
      try 
      { 
       string URI = ConfigurationManager.AppSettings["CommunicationmanagerURL"] + "PostUserEvent"; 
       var serializer = new JavaScriptSerializer(); 

       string requestData = serializer.Serialize(new 
       { 
        EventID = 1, 
        SubscriberID = studentId, 
        ToList = loginModel.EmailAddress, 
        TemplateParamVals = strStudentDetails, 
       }); 

       using (var client = new WebClient()) 
       { 
        client.Headers[HttpRequestHeader.ContentType] = "application/json"; 
        var result = client.UploadData(URI, Encoding.UTF8.GetBytes(requestData)); 

        return true; 
       } 
      } 
      catch (Exception ex) 
      { 
       // Log exceptions ... 
       return false; 
      } 
     }); 

    return uploadTask; 
} 
+0

試過,最後得到異步操作無法啓動...異常,所以去了包裝解決方案 – Codehelp

+0

我看到,編譯器警告你試圖等待一個不能等待的方法的問題。你目前正在嘗試使用一個任務來讓你的方法異步。您應該將您的調用包裝到UploadData中並返回。 –

0

的根本原因有點複雜;它與EAP components(如WebClient)如何通知他們的平臺他們正在工作有關。

最簡單的解決方案是用HttpClient替換WebClient