当你有服务器端代码(即一些ApiController)并且你的函数是异步的 - 所以它们返回Task<SomeObject>- 你认为最好的做法是等待你调用的函数ConfigureAwait(false)吗?
我已经读过它更高效,因为它不必将线程上下文切换回原始线程上下文.但是,使用ASP.NET Web Api,如果您的请求是在一个线程上进行的,并且等待某些函数和调用ConfigureAwait(false),则可能会在返回ApiController函数的最终结果时将您置于不同的线程上.
我在下面输入了一个我正在谈论的例子:
public class CustomerController : ApiController
{
public async Task<Customer> Get(int id)
{
// you are on a particular thread here
var customer = await SomeAsyncFunctionThatGetsCustomer(id).ConfigureAwait(false);
// now you are on a different thread! will that cause problems?
return customer;
}
}
Run Code Online (Sandbox Code Playgroud) 在过去的几天里,我测试了.net 4.5和c#5的新功能.
我喜欢它的新async/await功能.之前我曾使用BackgroundWorker通过响应式UI在后台处理更长的进程.
我的问题是:在拥有这些不错的新功能之后,我何时应该使用async/await和什么时候使用BackgroundWorker?两者的常见情况是什么?
c# backgroundworker task-parallel-library async-await .net-4.5
我发现了一些使用c#async/ awaitkeywords的异步编程的最佳实践(我是c#5.0的新手).
给出的建议之一是:
稳定性:了解同步上下文
...某些同步上下文是不可重入和单线程的.这意味着在给定时间内只能在上下文中执行一个工作单元.一个例子是Windows UI线程或ASP.NET请求上下文.在这些单线程同步上下文中,很容易使自己陷入僵局.如果从单线程上下文中生成任务,然后在上下文中等待该任务,则等待代码可能会阻止后台任务.
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)
如果我自己尝试剖析它,主线程会产生一个新线程MyWebService.GetDataAsync();,但由于主线程在那里等待,它等待结果GetDataAsync().Result.同时,说数据准备好了.为什么主线程不继续它的延续逻辑并从中返回字符串结果GetDataAsync()?
有人可以解释一下为什么上面的例子中存在死锁吗?我完全不知道问题是什么......
我试图使用Func与异步方法.我收到了一个错误.
无法将异步lambda表达式转换为委托类型
'Func<HttpResponseMesage>'.异步lambda表达式可能返回void,Task或者Task<T>都不能转换为'Func<HttpResponseMesage>'.
以下是我的代码:
public async Task<HttpResponseMessage> CallAsyncMethod()
{
Console.WriteLine("Calling Youtube");
HttpClient client = new HttpClient();
var response = await client.GetAsync("https://www.youtube.com/watch?v=_OBlgSz8sSM");
Console.WriteLine("Got Response from youtube");
return response;
}
static void Main(string[] args)
{
Program p = new Program();
Task<HttpResponseMessage> myTask = p.CallAsyncMethod();
Func<HttpResponseMessage> myFun =async () => await myTask;
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud) 在C#中,我有以下两个简单的例子:
[Test]
public void TestWait()
{
var t = Task.Factory.StartNew(() =>
{
Console.WriteLine("Start");
Task.Delay(5000).Wait();
Console.WriteLine("Done");
});
t.Wait();
Console.WriteLine("All done");
}
[Test]
public void TestAwait()
{
var t = Task.Factory.StartNew(async () =>
{
Console.WriteLine("Start");
await Task.Delay(5000);
Console.WriteLine("Done");
});
t.Wait();
Console.WriteLine("All done");
}
Run Code Online (Sandbox Code Playgroud)
第一个示例创建一个打印"开始"的任务,等待5秒打印"完成",然后结束任务.我等待任务完成,然后打印"全部完成".当我运行测试时,它按预期运行.
第二个测试应该具有相同的行为,除了由于使用async和await而在Task内部等待应该是非阻塞的.但是这个测试只是打印"开始"然后立即"完成所有"和"完成"从未打印.
我不知道为什么我会得到这种行为:S非常感谢任何帮助:)
Task.Delay()没有按预期运行,或者说我不理解它应该做什么.我正试图Task在C#中解决问题,以及如何Thread在我的实现中替换s.
我想要做的是这样的事情:
我已经通过Threads很好地实现了,但是所有很酷的孩子都说我应该使用Task,而不要触摸Thread.
所以对于代码我有这个(忽略[Test]- 这只是一种方便的尝试方法)
[Test]
public void ChattyTask()
{
var chattyTask = new Task(ChattyWriter);
chattyTask.Start();
chattyTask.Wait();
}
public void ChattyWriter()
{
int count = 0;
while (true)
{
var message = String.Format("Chatty Writer number {0}", count);
Trace.WriteLine(message);
count++;
Task.Delay(1000);
if (count >= 20)
{
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,测试以毫秒为单位完成,而不是像我期望的那样在20秒内完成.如果我更换Task.Delay()用Thread.Sleep(),一切正常,我也得到了一次打印第二.我试过添加async和await进入ChattyWriter(),但不仅它没有添加1秒延迟,它只打印一行而不是20行.
我究竟做错了什么?
可能它有助于描述我正在做的事情:我的项目使用外部API(RESTful),在我请求执行某些任务之后,我需要轮询API以检查任务是否已完成.外部任务可以长时间运行:1-15分钟.所以我需要在检查完成之间有一些延迟.并且可能有许多不同的并发进程与多个外部任务一起执行.我明白,如果我Thread.Sleep()在轮询时使用,那么同样的其他进程Thread将被阻止,没有充分的理由.
在Windows Phone 8中我有方法public async Task<bool> authentication().函数的返回类型是bool但当我尝试在if条件错误中使用其返回值时表示无法转换Task<bool>为bool.
public async Task<bool> authentication()
{
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string> ("user", _username),
new KeyValuePair<string, string> ("password", _password)
};
var serverData = serverConnection.connect("login.php", pairs);
RootObject json = JsonConvert.DeserializeObject<RootObject>(await serverData);
if (json.logined != "false")
{
_firsname = json.data.firsname;
_lastname = json.data.lastname;
_id = json.data.id;
_phone = json.data.phone;
_ProfilePic = json.data.profilePic;
_thumbnail = json.data.thumbnail;
_email = json.data.email;
return true;
}
else
return …Run Code Online (Sandbox Code Playgroud) 我按照Microsoft的Hello Key Vault示例应用程序中的示例在我的ASP.Net MVC Web应用程序上设置了Azure Keyvault .
Azure KeyVault(Active Directory)AuthenticationResult默认情况下有一个小时到期.因此,一小时后,您必须获得一个新的身份验证令牌.在获得我的第一个AuthenticationResult令牌后,KeyVault正在按预期工作,但在1小时到期后,它无法获得新令牌.
不幸的是,我的生产环境失败让我意识到这一点,因为我从未测试过去一小时的开发.
无论如何,经过两天多的努力弄清楚我的keyvault代码出了什么问题,我提出了一个解决方案来修复我的所有问题 - 删除异步代码 - 但感觉非常hacky.我想找出为什么它首先不起作用.
我的代码看起来像这样:
public AzureEncryptionProvider() //class constructor
{
_keyVaultClient = new KeyVaultClient(GetAccessToken);
_keyBundle = _keyVaultClient
.GetKeyAsync(_keyVaultUrl, _keyVaultEncryptionKeyName)
.GetAwaiter().GetResult();
}
private static readonly string _keyVaultAuthClientId =
ConfigurationManager.AppSettings["KeyVaultAuthClientId"];
private static readonly string _keyVaultAuthClientSecret =
ConfigurationManager.AppSettings["KeyVaultAuthClientSecret"];
private static readonly string _keyVaultEncryptionKeyName =
ConfigurationManager.AppSettings["KeyVaultEncryptionKeyName"];
private static readonly string _keyVaultUrl =
ConfigurationManager.AppSettings["KeyVaultUrl"];
private readonly KeyBundle _keyBundle;
private readonly KeyVaultClient _keyVaultClient;
private static async Task<string> GetAccessToken(
string authority, string resource, …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用"async"和"await"提供的功能来异步下载网页内容,我遇到了任务等待永远完成的问题.你可以告诉我下面的代码片段有什么问题吗?
protected void Page_Load(object sender, EventArgs e)
{
var websites = new string[] {"http://www.cnn.com","http://www.foxnews.com"};
var tasks = websites.Select(GenerateSomeContent).ToList();
//I don't want to use 'await Tasks.WhenAll(tasks)' as I need to block the
//page load until the all the webpage contents are downloaded
Task.WhenAll(tasks).Wait();
//This line is never hit on debugging
var somevalue = "Complete";
}
static async Task<Results> GenerateSomeContent(string url)
{
var client = new HttpClient();
var response = await client.GetAsync(url); //Await for response
var content = await response.Content.ReadAsStringAsync();
var output …Run Code Online (Sandbox Code Playgroud)