我正在C#Win8 CP上基于xaml的metro应用程序内部进行调用; 此调用只是命中一个Web服务并返回JSON数据.
HttpMessageHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/");
var result = await httpClient.GetStreamAsync("weeklyplan");
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[]));
return (WeeklyPlanData[])ser.ReadObject(result);
Run Code Online (Sandbox Code Playgroud)
它挂起,await但http呼叫几乎立即返回(通过提琴手确认); 就好像await被忽略了它只是挂在那里.
在您询问之前 - 是 - 打开了专用网络功能.
任何想法为什么会挂起?
我正在尝试测试以下的http请求方法
public async Task<HttpContent> Get(string url)
{
using (HttpClient client = new HttpClient())
// breakpoint
using (HttpResponseMessage response = await client.GetAsync(url))
// can't reach anything below this point
using (HttpContent content = response.Content)
{
return content;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,调试器似乎正在跳过第二条评论下面的代码.我正在使用Visual Studio 2015 RC,有什么想法吗?我也试过检查任务窗口,什么都没看到
编辑:找到解决方案
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleTests
{
class Program
{
static void Main(string[] args)
{
Program program = new Program();
var content = program.Get(@"http://www.google.com");
Console.WriteLine("Program finished");
}
public async Task<HttpContent> Get(string url)
{
using (HttpClient …Run Code Online (Sandbox Code Playgroud) 我正在尝试基于VS2013项目模板中的示例AccountController为ASP.NET MVC5网站设置电子邮件确认.我已经实现了IIdentityMessageService使用SmtpClient,试图尽可能简单:
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using(var client = new SmtpClient())
{
var mailMessage = new MailMessage("some.guy@company.com", message.Destination, message.Subject, message.Body);
await client.SendMailAsync(mailMessage);
}
}
}
Run Code Online (Sandbox Code Playgroud)
调用它的控制器代码直接来自模板(由于我想排除其他可能的原因,因此将其解压缩为单独的操作):
public async Task<ActionResult> TestAsyncEmail()
{
Guid userId = User.Identity.GetUserId();
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userId, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(userId, "Confirm your account", "Please confirm your account by clicking <a …Run Code Online (Sandbox Code Playgroud) 我有一个搜索操作有两个路径,一个只返回一个简单视图的同步路径,一个异步路径,异步执行搜索,然后返回一个视图.两者都是GET请求,因此它们是同一行动的一部分.
问题是当我访问动作"localhost:XXXX/Home/Search"时,页面无限加载.使用Fiddler,我可以看到请求永远不会返回.我调试了它,它使它到最后一行代码,但是,再次,请求没有完成.
我已将repro简化为以下内容:
public async Task<ActionResult> Search()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
VS11警告我,代码将在没有等待的情况下同步运行,这很好,但请求没有完成.
这有用吗?或者我需要在这里做点什么吗?
编辑
这是针对.NET 4.5的MVC 4.
编辑2
对于那些在代码中看得更清楚的人来说,这就是我在异步操作中需要同步的原因:
public async Task<ActionResult> Search(string query = null)
{
if (string.IsNullOrWhiteSpace(query))
return View(new SearchViewModel()); // never loads
var model = await _someService.SearchAsync(query);
return View(model); // loads
}
Run Code Online (Sandbox Code Playgroud) 关于如何避免HttpClient从同步代码调用的异步代码(例如,方法)中的死锁,有很多问题,如下所示.我知道避免这些死锁的各种方法.
相反,我想了解在测试期间加剧或触发错误代码中的这些死锁的策略.
这是最近给我们带来问题的坏代码示例:
public static string DeadlockingGet(Uri uri)
{
using (var http = new HttpClient())
{
var response = http.GetAsync(uri).Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
}
Run Code Online (Sandbox Code Playgroud)
它是从一个ASP.NET应用程序调用的,因此具有非null值SynchronizationContext.Current,它为潜在的僵局火灾提供了燃料.
除了公然滥用HttpClient之外,这个代码在我们公司的一个服务器中陷入僵局......但只是零星地.
我在QA工作,所以我尝试通过一个单元测试重新编写死锁,该单元测试命中Fiddler的侦听器端口的本地实例:
public class DeadlockTest
{
[Test]
[TestCase("http://localhost:8888")]
public void GetTests(string uri)
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
var context = SynchronizationContext.Current;
var thread = Thread.CurrentThread.ManagedThreadId;
var result = DeadlockingGet(new Uri(uri));
var thread2 = Thread.CurrentThread.ManagedThreadId;
}
}
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
默认情况下,单元测试具有null SynchronizationContext.Current, …
我正在使用带有.Net 4.5和ASP MVC 4 RC的Visual Studio 2012 RC.每当我使用异步时它就会挂起.控制器操作方法使用异步,但本身不是异步控制器方法.
没有记录错误或抛出异常,但浏览器永远显示"正在等待www.myweb.local ".
// Simplest possible async
public class Waiter
{
public async Task<int> GetValue()
{
await Task.Yield();
return await Task.Factory.StartNew(() => 42);
}
}
// simplest possible controller that uses the async
public class HomeController : Controller
public ActionResult Index()
{
var waiter = new Waiter();
var resultTask = waiter.GetValue();
int result = resultTask.Result;
// it never gets here
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
我已经完成了这个答案中提到的事情,但它仍然不起作用.即.web.config包含
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
Run Code Online (Sandbox Code Playgroud)
魔术词await …
我正在使用Xamarin(Android)构建应用程序,它使用PCL项目作为服务层.我有一个Web Api端点,我正在使用HttpClient它.
一切正常,但是如果我让我的Android应用程序打开并闲置一段时间(比如2分钟)并且我尝试发出新请求,那么使用单例的第一个请求HttpClient将无效.它永远不会返回并保持在那里直到超时(TaskCancelledException).我也在我的Api上设置了一个断点,它没有被击中.如果我再次尝试发送请求,那么它可以工作.
经过大量的调试后,我发现只有当我尝试使用HttpClient单例作为单例时才会发生这种情况.如果我HttpClient为每个请求创建一个新的一切都有效.
起初我认为这是一个僵局问题,我做了很多研究,并按照其他答案和Stephen Cleary的优秀帖子所描述的指导原则进行了双重检查,我几乎可以肯定事实并非如此.
我正在使用ConfigureAwait(false)来自我的PCL项目的每次调用,因此它不会捕获上下文.
在Android片段内:
SampleService svc = new SampleService();
response = await svc.GetAllSamples();
Run Code Online (Sandbox Code Playgroud)
这个服务叫(在我的PCL项目中):
public class SampleService
{
public HttpClient Client { get; set; }
public SampleService()
{
// resolves my singleton instance and uses my custom DelegatingHandler
Client = CustomHttpClient.Instance;
}
public async Task<IEnumerable<Sample>> GetAllSamples()
{
IEnumerable<Sample> list = null;
// this never returns and timeouts the first …Run Code Online (Sandbox Code Playgroud) 我一直在努力与异步/等待一周.一些背景知识:下面的代码是MVC4网站项目的一部分.该网站发生了大量的API调用.目标是使这些API调用并行发生而不是同步,以提高站点响应能力.现在所有API调用都相互阻塞.因此,如果一个页面需要4个调用...更长的加载时间.
我已经为所有API调用的同步和异步版本构建了单独的方法.我遇到的问题是await永远不会响应.我认为这与这个问题有关.但是,我真的不确定如何解决它.我已经尝试过ConfigureAwait(false),这对我没有帮助.
这是代码:
控制器中的初始调用看起来像这样:
BaseData bdata = API.GetBaseData().Result;
Run Code Online (Sandbox Code Playgroud)
我很乐意在这里使用await,但是如果没有AsyncController这不是一个选项,由于需要请求/响应访问,我们无法使用它.其他方法在API类中:
internal static async Task<BaseData> GetBaseData() {
var catTask = GetParentCategoriesAsync();
var yearTask = GetYearsAsync();
await Task.WhenAll(new Task[] { catTask, yearTask });
var bdata = new BaseData {
years = await yearTask,
cats = await catTask
};
return bdata;
}
internal static async Task<List<APICategory>> GetParentCategoriesAsync() {
try {
WebClient wc = new WebClient();
wc.Proxy = null;
string url = getAPIPath();
url += "GetFullParentCategories";
url += "?dataType=JSON";
Uri targeturi = new …Run Code Online (Sandbox Code Playgroud) 当我在控制台应用程序中调用下面的函数时,它只是工作.但是当我将它添加到MVC控制器时,执行永远不会到达JsonConvert行.任何想法,我错过了什么.
调用代码
GetVersion(url).Result.FileVersion
Run Code Online (Sandbox Code Playgroud)
方法
public static async Task<Version> GetVersion(string url, string hostHeader)
{
var client = new HttpClient();
if (!string.IsNullOrEmpty(hostHeader))
{
client.DefaultRequestHeaders.Host = hostHeader;
}
var version = await client.GetStringAsync(url);
var output = JsonConvert.DeserializeObject<Version>(version);
client.Dispose();
return output;
}
Run Code Online (Sandbox Code Playgroud) 我正在构建一个ASP.NET WebApi 2.1应用程序,该应用程序需要与HttpContext.Items等效的每个请求缓存。
我什至不能在IIS托管下使用HttpContext,因为在服务/回购层(HttpContext.Current变为异步工作)时,HttpContext似乎丢失了(使用TPL调用,由于某些接口需要匹配,因此不进行异步/等待)空值)。
我使用的是unity 3.5,无法实现按请求进行正确的注入。尝试了HttpControllerActivator方法:
public class HttpControllerActivator : IHttpControllerActivator
{
private readonly IUnityContainer _container;
private readonly IHttpControllerActivator _activator;
public HttpControllerActivator(IUnityContainer container, IHttpControllerActivator activator)
{
_container = container;
_activator = activator;
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
IHttpController controller = _activator.Create(request, controllerDescriptor, controllerType);
_container.RegisterInstance<System.Net.Http.HttpRequestMessage>(request, new HierarchicalLifetimeManager());
return controller;
}
}
Run Code Online (Sandbox Code Playgroud)
但这会将HttpRequestMessage注册在根容器上,而不是在_activator.Create内部由BeginScope()调用创建的子容器上。结果,我在并发负载下得到混合请求实例。
知道如何解决这个问题吗?两天以来我一直在网上搜索,因此没有找到任何真正的解决方案...
async-await ×8
c# ×8
asp.net-mvc ×3
asynchronous ×2
.net ×1
.net-4.5 ×1
deadlock ×1
qa ×1
smtpclient ×1