我有一个async不返回任何数据的方法:
public async Task MyAsyncMethod()
{
// do some stuff async, don't return any data
}
Run Code Online (Sandbox Code Playgroud)
我从另一个返回一些数据的方法调用它:
public string GetStringData()
{
MyAsyncMethod(); // this generates a warning and swallows exceptions
return "hello world";
}
Run Code Online (Sandbox Code Playgroud)
在MyAsyncMethod()没有等待的情况下进行呼叫会导致" 因为此呼叫未被等待,当前方法在呼叫完成之前继续运行 "在visual studio中发出警告.在该警告的页面上,它指出:
只有当您确定不想等待异步调用完成并且被调用的方法不会引发任何异常时,才应考虑禁止警告.
我确定我不想等待电话完成; 我不需要或没有时间.但这一呼吁可能引发例外.
我偶然发现了这个问题几次,我确信这是一个必须有共同解决方案的常见问题.
如何在不等待结果的情况下安全地调用异步方法?
对于那些建议我等待结果的人来说,这是响应我们的Web服务(ASP.NET Web API)上的Web请求的代码.在UI上下文中等待保持UI线程空闲,但是在Web请求调用中等待将在响应请求之前等待任务完成,从而无缘无故地增加响应时间.
我有以下测试WebAPI代码,我没有在生产中使用WebAPI但我之所以这样做是因为我对这个问题进行了讨论:WebAPI异步问题
无论如何,这是违规的WebAPI方法:
public async Task<string> Get(int id)
{
var x = HttpContext.Current;
if (x == null)
{
// not thrown
throw new ArgumentException("HttpContext.Current is null");
}
await Task.Run(() => { Task.Delay(500); id = 3; });
x = HttpContext.Current;
if (x == null)
{
// thrown
throw new ArgumentException("HttpContext.Current is null");
}
return "value";
}
Run Code Online (Sandbox Code Playgroud)
我曾经相信第二个异常是预期的,因为当await完成时,它可能会在一个不同的线程上,HttpContext.Current因为线程静态变量将不再解析为适当的值.现在,基于同步上下文,实际上它可能会在等待之后被强制返回到同一个线程但我在测试中没有做任何奇特的事情.这只是一个简单,天真的用法await.
在另一个问题的评论中,我被告知HttpContext.Current在等待之后应该解决.对这个问题甚至还有另一个评论,表明同样的问题.什么是真的?应该解决吗?我想不,但我想要一个权威的答案,因为async它await是新的,我找不到任何确定的东西.
TL; DR:HttpContext.Current可能null在一个await?
我使用基于任务的操作生成了代理.
如何使用async/await 正确调用此服务(处理ServiceClient和OperationContext之后)?
我的第一次尝试是:
public async Task<HomeInfo> GetHomeInfoAsync(DateTime timestamp)
{
using (var helper = new ServiceHelper<ServiceClient, ServiceContract>())
{
return await helper.Proxy.GetHomeInfoAsync(timestamp);
}
}
Run Code Online (Sandbox Code Playgroud)
作为ServiceHelper一个创造ServiceClient和OperationContextScope后来处理它们的类:
try
{
if (_operationContextScope != null)
{
_operationContextScope.Dispose();
}
if (_serviceClient != null)
{
if (_serviceClient.State != CommunicationState.Faulted)
{
_serviceClient.Close();
}
else
{
_serviceClient.Abort();
}
}
}
catch (CommunicationException)
{
_serviceClient.Abort();
}
catch (TimeoutException)
{
_serviceClient.Abort();
}
catch (Exception)
{
_serviceClient.Abort();
throw;
}
finally …Run Code Online (Sandbox Code Playgroud) 我们有一个.NET应用程序,可以对各种Web服务进行多次并发调用,收集它们的响应,然后根据这些响应进行一些计算.在尝试获得额外性能时,我一直在研究使用通过使用IO完成端口来使用.NET的IO线程的方法.我已经阅读了几个资源,包括Joe Duffy最近出版的"Windows上的并发编程"一书,当我"了解"它们的用处时,我对它们在.NET中的行为有点不清楚,我正在寻找一个简洁的解释.
我正在尝试使用 async 返回结果,但我希望它返回整个对象而不是返回数据
[System.Web.Services.WebMethod(BufferResponse=false)]
public static async Task<bool> getLogin(string username, string password)
{
Login login = new Login();
Task<bool> loginVerify = login.verifyLogin(username,password);
await loginVerify;
return loginVerify.Result;
}
public class Login
{
public async Task<bool> verifyLogin(string username, string password)
{
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
Firefox Firebug 的结果显示:
{"d":{"Result":true,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false}}
Run Code Online (Sandbox Code Playgroud)
为什么不只是显示结果?
我试过跑步
public static async Task<bool> getLogin(string username, string password)
{
Login login = new Login();
Task<bool> loginVerify = login.verifyLogin(username,password);
await loginVerify;
return false;
}
Run Code Online (Sandbox Code Playgroud)
但是萤火虫报告是相同的,只是它在 json 中说 Result false
{"d":{"Result":false,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false}}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是为什么它显示整个对象而不是结果?
async-await ×4
c# ×4
.net ×2
asp.net ×2
concurrency ×1
exception ×1
jquery ×1
performance ×1
task ×1
wcf ×1
webmethod ×1