HttpClient.GetAsync(...)在使用等待/异步时从不返回(HttpClient.GetAsync(…) never returns when using await/async)
编辑: 这个问题看起来可能是同一个问题,但没有回应...
编辑:在测试用例5中,任务似乎被卡在
WaitingForActivation
状态。我使用.NET 4.5中的System.Net.Http.HttpClient遇到了一些奇怪的行为 - 其中“等待”调用结果(例如)
httpClient.GetAsync(...)
将永远不会返回。这仅在使用新的异步/等待语言功能和Tasks API的某些情况下发生 - 代码总是似乎在仅使用延续时才起作用。
以下是一些重现问题的代码 - 将其放入Visual Studio 11中的一个新的“MVC 4 WebApi项目”,以显示以下GET端点:
/api/test1 /api/test2 /api/test3 /api/test4 /api/test5 <--- never completes /api/test6
这里的每个端点返回相同的数据(来自stackoverflow.com的响应头),除了
/api/test5
,从未完成。我在HttpClient类中遇到了错误,还是以某种方式滥用API?
复制代码:
public class BaseApiController : ApiController { /// <summary> /// Retrieves data using continuations /// </summary> protected Task<string> Continuations_GetSomeDataAsync() { var httpClient = new HttpClient(); var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString()); } /// <summary> /// Retrieves data using async/await /// </summary> protected async Task<string> AsyncAwait_GetSomeDataAsync() { var httpClient = new HttpClient(); var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return result.Content.Headers.ToString(); } } public class Test1Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await Continuations_GetSomeDataAsync(); return data; } } public class Test2Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = Continuations_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test3Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return Continuations_GetSomeDataAsync(); } } public class Test4Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await AsyncAwait_GetSomeDataAsync(); return data; } } public class Test5Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = AsyncAwait_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test6Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return AsyncAwait_GetSomeDataAsync(); } }
Edit: This question looks like it might be the same problem, but has no responses...
Edit: In test case 5 the task appears to be stuck in
WaitingForActivation
state.I've encountered some odd behaviour using the System.Net.Http.HttpClient in .NET 4.5 - where "awaiting" the result of a call to (e.g.)
httpClient.GetAsync(...)
will never return.This only occurs in certain circumstances when using the new async/await language functionality and Tasks API - the code always seems to work when using only continuations.
Here's some code which reproduces the problem - drop this into a new "MVC 4 WebApi project" in Visual Studio 11 to expose the following GET endpoints:
/api/test1 /api/test2 /api/test3 /api/test4 /api/test5 <--- never completes /api/test6
Each of the endpoints here return the same data (the response headers from stackoverflow.com) except for
/api/test5
which never completes.Have I encountered a bug in the HttpClient class, or am I misusing the API in some way?
Code to reproduce:
public class BaseApiController : ApiController { /// <summary> /// Retrieves data using continuations /// </summary> protected Task<string> Continuations_GetSomeDataAsync() { var httpClient = new HttpClient(); var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString()); } /// <summary> /// Retrieves data using async/await /// </summary> protected async Task<string> AsyncAwait_GetSomeDataAsync() { var httpClient = new HttpClient(); var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead); return result.Content.Headers.ToString(); } } public class Test1Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await Continuations_GetSomeDataAsync(); return data; } } public class Test2Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = Continuations_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test3Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return Continuations_GetSomeDataAsync(); } } public class Test4Controller : BaseApiController { /// <summary> /// Handles task using Async/Await /// </summary> public async Task<string> Get() { var data = await AsyncAwait_GetSomeDataAsync(); return data; } } public class Test5Controller : BaseApiController { /// <summary> /// Handles task by blocking the thread until the task completes /// </summary> public string Get() { var task = AsyncAwait_GetSomeDataAsync(); var data = task.GetAwaiter().GetResult(); return data; } } public class Test6Controller : BaseApiController { /// <summary> /// Passes the task back to the controller host /// </summary> public Task<string> Get() { return AsyncAwait_GetSomeDataAsync(); } }
原文:https://stackoverflow.com/questions/10343632
最满意答案
尝试像这样格式化导入(而不是在媒体查询中):
@import url(foo.css) screen and (min-width:320px); @import url(bar.css) screen and (min-device-width:768px) and (orientation:portrait); @import url(blah.css) screen and (min-device-width:768px) and (orientation:landscape);
Try formatting your imports like this (instead of inside a media query):
@import url(foo.css) screen and (min-width:320px); @import url(bar.css) screen and (min-device-width:768px) and (orientation:portrait); @import url(blah.css) screen and (min-device-width:768px) and (orientation:landscape);
相关问答
更多-
定向平板电脑与手机(orientation tablet vs phone)[2022-04-06]
阅读这篇文章: http : //android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.html 此外,请勿在活动可见时使用唤醒锁定以保持屏幕开启。 改为在视图上使用KEEP_SCREEN_ON标志,您可以删除唤醒锁定权限。 Read this post: http://android-developers.blogspot.com/2010/09/one-screen-turn-deserves-another.h ... -
如何使用媒体查询分离手机与平板电脑肖像与平板电脑景观(how to use media query to seperate phone vs tablet portrait vs tablet landscape)[2023-06-24]
尝试像这样格式化导入(而不是在媒体查询中): @import url(foo.css) screen and (min-width:320px); @import url(bar.css) screen and (min-device-width:768px) and (orientation:portrait); @import url(blah.css) screen and (min-device-width:768px) and (orientation:landscape); Try forma ... -
IMO这些是最好的断点: @media (min-width:320px) { /* smartphones, portrait iPhone, portrait 480x320 phones (Android) */ } @media (min-width:480px) { /* smartphones, Android phones, landscape iPhone */ } @media (min-width:600px) { /* portrait tablets, portrait iPa ...
-
其他答案已经解决了屏幕检测任务。 但是,仍然存在检测代码是否在Tablet设备上运行的问题。 您可以使用react-native-device-info包检测它,特别是它的isTablet方法。 因此,作为示例,在您的组件中: constructor(){ super(); this.state = {orientation: 'UNKNOWN'} this._onOrientationChanged = this._onOrientationChanged.bind(this); } _on ...
-
您可以使用navigator.userAgent来获取设备类型。 例如这样的事情: var deviceType = (navigator.userAgent.match(/iPad/i)) == "iPad" ? "iPad" : (navigator.userAgent.match(/iPhone/i)) == "iPhone" ? "iPhone" : (navigator.userAgent.match(/Android/i)) == "Android" ? "Android" : (navig ...
-
我认为问题在于您的SCSS对于平板电脑部分略有不同。 尝试这个: $tablet: ( columns: 12, gutter: 1.1em, media: 'screen and (min-width 768px) and (max-width 1024px)' ); I think the issue is that your SCSS is slightly wrong for the tablet section. Try this: $tablet: ( columns: 12, gu ...
-
不是正统的方式,但你可以像这样实现它,创建2个资源文件一个通用,一个用于sw600dp(平板电脑)并添加一个bool“istablet” 然后在你的活动OnCreate方法 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(!getResources().getBoolean(R.bool.is_tabl ...
-
我认为你需要使用2个标志,而不仅仅是一个。 首先是 android:screenOrientation='landscape' 第二是 android:configChanges="orientation" 首先会告诉android在横向模式下运行活动,其中第二个将告诉android即使用户旋转手机也不会改变方向。 基本上使用第二个标志,您将覆盖方向配置更改。 I think you need to use 2 flags, not just one. First is android:screenO ...
-
我相信你可以在res / layout文件夹中创建一个子文件夹,名为xlarge-land和xlarge-port,其中包含xml文件。 设备本身将知道要加载什么xml。 res/layout/my_layout.xml // layout for normal screen size ("default") res/layout-small/my_layout.xml // layout for small screen size res/layout-large/my ...
-
针对目标移动设备(第一),平板电脑和桌面的特定媒体查询(Specific media queries for target mobile (first), tablet & desktop)[2022-01-27]
使用Modernizr( http://modernizr.com/download/ )检测触摸设备。 Modernizr会将.touch或.no-touch类添加到您的html标签中。 因此,对于桌面,您将使用.touch类来定位桌面。 @media only screen and (min-width: 960px) { .touch .container { width: 960px; } } Use Modernizr (http://modernizr.com/download/) t ...