2014-03-24 26 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