2014-10-07 42 views
0

我一直在这个问题上摸不着头脑。我不知道这个异常被抛出的位置。我该在哪里碰到这个异常?这是一个System.Net.WebException。我想我只是没有得到任务和异步/等待。我知道我正在创建其他线程,这是伟大的,但我在哪里处理异常?无法捕捉任务抛出的异常

The remote server returned an error: (403) Forbidden.

下面是代码:

public async void sendRequest(string database, string table, string where, bool isPost, int deviceType) 
{ 
    string urlQuery = Constants.URL_QUERY + database + "/" + table + "?" + where; 

    Debug.WriteLine("URL Query: " + urlQuery); 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlQuery); 
    request.Method = isPost ? "POST" : "GET"; 
    request.ContentType = "application/json"; 

    try 
    { 
     Debug.WriteLine("getting response"); 
     WebResponse response = await makeAsyncRequest(request); 
     Debug.WriteLine("response obtained"); 
     finishRequest(response); 
    } 
    catch (WebException e) 
    { 
     Debug.WriteLine("WebException caught"); 
    } 
} 

private async static Task<WebResponse> makeAsyncRequest(HttpWebRequest req) 
{ 
    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null); 

    await task.ContinueWith(t => 
    { 
     if (t.IsFaulted) 
     { 
      Debug.WriteLine("It's faulted."); 
      t.Exception.Handle((x) => 
      { 
       if (x is WebException) 
       { 
        Debug.WriteLine("It's a web exception"); 
        return true; 
       } 
       Debug.WriteLine("Exception?: " + x); 
       return false; 
      }); 
     } 
    }); 
    Debug.WriteLine("returning task"); 
    return task.Result; 
} 

private static void finishRequest(WebResponse response) 
{ 
    Debug.WriteLine("finishRequest called"); 
} 

以下是我在输出窗口中看到:

2014-10-07 14:05:05.104 FormsTemplateiOS[1568:53280] getting response 
[0:] getting response 
Thread started: #3 
Thread started: <Thread Pool> #4 
Thread started: <Thread Pool> #5 
Thread started: <Thread Pool> #6 
Thread started: <Thread Pool> #7 
Thread started: #8 
[0:] 
2014-10-07 14:05:05.681 FormsTemplateiOS[1568:53326] It's faulted. 
[0:] It's faulted. 
[0:] 
2014-10-07 14:05:05.804 FormsTemplateiOS[1568:53326] It's a web exception 
[0:] It's a web exception 
Unhandled Exception: 

System.Net.WebException: The remote server returned an error: (403) Forbidden. 

Unhandled Exception: 
System.Net.WebException: The remote server returned an error: (403) Forbidden. 
    at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1718 
    at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1485 
The program 'Mono' has exited with code 0 (0x0). 
Debugging session ended. 

编辑:

我每斯蒂芬·克利里更新makeAsyncRequest(HttpWebRequest)建议。我仍然有同样的问题。

private async static Task<WebResponse> makeAsyncRequest(HttpWebRequest req) 
{ 
    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null); 
    try 
    { 
     return await task; 
    } 
    catch (WebException e) 
    { 
     Debug.WriteLine("It's a WebException"); 
    } 
    catch (Exception e) 
    { 
     Debug.WriteLine("Other Exception"); 
    } 
    return null; 
} 

输出窗口:

2014-10-07 14:32:08.385 FormsTemplateiOS[1588:57008] getting response 
[0:] getting response 
Thread started: #3 
Thread started: <Thread Pool> #4 
Thread started: <Thread Pool> #5 
Thread started: <Thread Pool> #6 
Thread started: <Thread Pool> #7 
Thread started: #8 
Unhandled Exception: 

System.Net.WebException: The remote server returned an error: (403) Forbidden. 

Unhandled Exception: 
System.Net.WebException: The remote server returned an error: (403) Forbidden. 
    at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1718 
    at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.0.0.63/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1485 
The program 'Mono' has exited with code 0 (0x0). 
Debugging session ended. 
+0

_。我不知道这个异常被抛出的位置_你是否试图看看StackTrace? – 2014-10-07 19:04:15

+0

将输出添加到问题。 – 2014-10-07 19:06:03

+0

启用[抛出异常时中断](http://msdn.microsoft.com/zh-cn/library/d14azbfh.aspx)。调试器将停止在发生异常的地方。其他选项是检查StackTrace – 2014-10-07 19:06:32

回答

4

我明白我创建其他线程,这是伟大的,所有

不,实际上。您可能需要阅读我的async intro

另外:

  • 避免async void。使用await代替ContinueWith

您可能还会发现我的async best practices文章有帮助。

private async static Task<WebResponse> MakeRequestAsync(HttpWebRequest req) 
{ 
    Task<WebResponse> task = Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null); 
    try 
    { 
    return await task; 
    } 
    catch (WebException ex) 
    { 
    Debug.WriteLine("It's a web exception"); 
    } 
    catch (Exception ex) 
    { 
    Debug.WriteLine("It's not a web exception."); 
    } 
} 

最后一点,可以考虑使用HttpClient代替HttpWebRequestHttpClient被设计用于async的使用。

+0

如果任务不在单独的线程中,那么为什么它是System.Threading的一部分? – 2014-10-07 19:10:35

+3

这是历史原因。 “Task”最初是作为Task Parallel Library的一部分引入的,它主要用于表示要在线程上执行的工作。它已被重新用作任意“异步操作”。 – 2014-10-07 19:12:01

+0

我需要能够将请求标头和方法设置为POST或GET。这可以用HttpClient完成吗?滚动浏览属性和方法,我没有看到任何会允许的。 – 2014-10-07 19:25:52