Tag: async await

使用DynamicProxy拦截对异步方法的调用

下面是实现Castle动态代理库的IInterceptor的自定义类型上的Intercept方法的代码。 此代码段来自此处发布的基于AOP的日志记录概念validation控制台应用程序。 public void Intercept(IInvocation invocation) { if (Log.IsDebugEnabled) Log.Debug(CreateInvocationLogString(“Called”, invocation)); try { invocation.Proceed(); if (Log.IsDebugEnabled) if (invocation.Method.ReturnType != typeof(void)) Log.Debug(“Returning with: ” + invocation.ReturnValue); } catch (Exception ex) { if (Log.IsErrorEnabled) Log.Error(CreateInvocationLogString(“ERROR”, invocation), ex); throw; } } 这在常规方法调用中按预期工作,但在使用async方法(使用C#5.0中的async/await关键字)尝试时则不行。 我相信,我也理解这背后的原因。 为了使async/await工作,编译器将方法的function体添加到幕后的状态机中,一旦遇到无法同步完成的第一个awaitable表达式,控件将返回给调用者。 此外,我们可以询问返回类型并确定我们是否正在处理这样的async方法: if (invocation.Method.ReturnType == typeof(Task) || (invocation.Method.ReturnType.IsGenericType && invocation.Method.ReturnType.GetGenericTypeDefinition() == typeof(Task))) Log.Info(“Asynchronous method found…”); […]

使用Async和Await转换普通的Http Post Web请求

我如何使用Async / Await模式转换我的传统HttpWebRequest“POST”调用,这里有我附加我当前的代码,任何人请帮我转换此代码使用Windows Phone 8的Async / Await模式。 public void GetEnvironmentVariables(Action getResultCallback, Action getErrorCallback) { CredentialsCallback = getResultCallback; ErrorCallback = getErrorCallback; var uri = new Uri(BaseUri); var request = (HttpWebRequest)WebRequest.Create(uri); request.Method = “POST”; request.ContentType = “application/json”; var jsonObject = new JObject { new JProperty(“apiKey”,_api), new JProperty(“affiliateId”,_affid), }; var serializedResult = JsonConvert.SerializeObject(jsonObject); byte[] requestBody = Encoding.UTF8.GetBytes(serializedResult); request.BeginGetRequestStream(GetRequestStreamCallback, […]

在递归方法中使用async / await的正确方法是什么?

在递归方法中使用async / await的正确方法是什么? 这是我的方法: public string ProcessStream(string streamPosition) { var stream = GetStream(streamPosition); if (stream.Items.count == 0) return stream.NextPosition; foreach(var item in stream.Items) { ProcessItem(item); } return ProcessStream(stream.NextPosition) } 以下是使用async / await的方法: public async Task ProcessStream(stringstreamPosition) { var stream = GetStream(streamPosition); if (stream.Items.count == 0) return stream.NextPosition; foreach(var item in stream.Items) { await ProcessItem(item); //ProcessItem() […]

使用Entity Framework异步方法和SQL Server Compact阻止行为

我有一个MVVM应用程序调用数据服务来获取一些数据绑定。 数据服务通过Entity Framework 6访问SQL Server Compact(v4.0)数据库。 数据(当前)需要几秒钟才能加载,当同步调用时(这并不奇怪)会阻止GUI线程。 我假设大部分都是IO绑定所以我添加了一个等效的Async方法以异步方式执行数据加载,以允许GUI保持响应。 但是,当我使用EF Async方法时,它似乎没有任何区别,GUI线程仍会阻塞大致相同的时间。 我知道使用Async调用不会将工作移动到不同的线程,但是我已经假定这个活动的大部分是IO绑定的。 因此,使用EF Async方法应该允许调用(GUI)线程继续做其他工作,但它没有任何区别。 例如,如果我编写LoadData方法以使用EF同步加载方法,则GUI将阻塞,直到加载数据: public ObservableCollection GetData() { //Do IO bound activity… Context.DataTable1.Include(…).Load(); //for demo purposes, just return some data return Context.DataTable1.Local; //(ObservableCollection) } 加载数据的Async方法如下所示: public async Task<ObservableCollection> GetDataAsync() { //Do IO bound activity… var task = Context.DataTable1.Include(…).LoadAsync(); await task; //for demo purposes, just return […]

可以在CoreCLR上使用’async’修饰符标记入口点?

在Stephan Cleary最近关于.NET CoreCLR上的异步控制台应用程序的博客文章中,他向我们展示了在CoreCLR中(当前在Visual Studio 2015上运行,CTP6),入口点“Main”实际上可以标记为async Task ,正确编译并实际运行: public class Program { public async Task Main(string[] args) { Console.WriteLine(“Hello World”); await Task.Delay(TimeSpan.FromSeconds(1)); Console.WriteLine(“Still here!”); Console.ReadLine(); } } 给出以下输出: 这是由ASP.NET团队的一篇名为“深度潜水”的博客文章强化到ASP.NET 5运行时 : 除了静态的Program.Main入口点,KRE还支持基于实例的入口点。 您甚至可以使主入口点异步并返回任务。 通过使主入口点成为实例方法,您可以将运行时环境中的服务注入到应用程序中。 我们知道,到目前为止, 无法使用’async’修饰符标记入口点 。 那么,在新的CoreCLR运行时中,这实际上是如何实现的呢?

为什么抛出TaskCanceledException并且不会总是进入调试器

我正在深入研究async-await机制并观察到抛出一个我无法解释的TaskCanceledException 。 在下面的示例中(自包含)我有声明 await Task.Run(() => null); 我知道这个语句本身是无用的,但我把问题分开了,真正的代码有逻辑,在某些情况下返回null。 为什么抛出TaskCanceledException ? 如果我返回一个任意数字(在下面的例子中为5),它就不会抛出。 此外,如果我await该方法VS的调试器中断,但如果我不await它,则只有一条消息被写入VS的输出窗口。 internal class Program { private static void Main(string[] args) { var testAsync = new TestAsync(); // Exception thrown but the debugger does not step in. Only a message is logged to the output window testAsync.TestAsyncExceptionOnlyInTheOutputWindow(); // Exception thrown and the debugger breaks testAsync.TestAsyncExceptionBreaksIntoTheDebugger(); […]

将数据异步加载到Windows窗体中的DataTable中

我正在修改旧的WinForms / ADO应用程序的数据访问层,以通过异步developerforce rest api使用soql来获取Salesforce对象。 以下方法通常有效,除了我的十三个表例程之一永远不会从AddMyTableRow(System.Data.DataRowCollection.Add())方法返回: public void LoadData() { var tasks = new List<Task> { GetObject1Async(), GetObject2Async(),… GetObject13Async() }; Task.WaitAll(tasks.ToArray()); //do some postprocessing now that I have all the data } async Task GetObject1Async(){ var response = await cnx.QueryAsync(“SELECT foo FROM bar”).ConfigureAwait(false); foreach (var rec in response.Records){ var row = MyDataSet.MyTable.NewMyTableRow(); row.Name = rec.Name; […]

通过等待每个任务异步转换IEnumerable <Task >

今天我想知道如何通过等待每个任务来转换任务列表。 请考虑以下示例: private static void Main(string[] args) { try { Run(args); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.ReadLine(); } } static async Task Run(string[] args) { //Version 1: does compile, but ugly and List overhead var tasks1 = GetTasks(); List gainStrings1 = new List(); foreach (Task task in tasks1) { gainStrings1.Add(await task); } Console.WriteLine(string.Join(“”, […]

现在VS 2012发布后,正确使用VS和Async的方法是什么?

由于工作限制,我需要在不久的将来继续使用Visual Studio 2010。 与此同时,我在个人编码中一直在学习Async。 最新的Async CTP是否与C#5.0的Async语言function完全一致? 是否正在安装Async CTP以正确使用VS2010的Async?

取消令牌的任务?

鉴于取消令牌,我想创建一个等待它的任务,这是永远不会完成但可以取消。 我需要这样的模式,IMO应该很常见: async Task DoStuff(Task t, CancellationToken ct) { // t was made from TaskCompletionSource, // both t and ct are beyond my control Task t2 = TaskFromCancellationToken(ct); await Task.WhenAny(t, t2); // do stuff } 我到目前为止最好的想法是: Task TaskFromCancelationToken(CancellationToken ct) { return Task.Delay(Timeout.Infinite, ct); } 是否有更好的方法来实现这种逻辑?