Tag: async await

为什么GC在我引用它时会收集我的对象?

让我们看一下显示问题的以下片段。 class Program { static void Main(string[] args) { var task = Start(); Task.Run(() => { Thread.Sleep(500); Console.WriteLine(“Starting GC”); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine(“GC Done”); }); task.Wait(); Console.Read(); } private static async Task Start() { Console.WriteLine(“Start”); Synchronizer sync = new Synchronizer(); var task = sync.SynchronizeAsync(); await task; GC.KeepAlive(sync);//Keep alive or any method call doesn’t help sync.Dispose();//I need […]

在C#7中,我如何“滚动自己的”类似任务的类型与异步一起使用?

C#7中一个较少谈论的function是“通用异步返回类型”,微软将其描述为: 从异步方法返回Task对象可能会在某些路径中引入性能瓶颈。 Task是一个引用类型,因此使用它意味着分配一个对象。 如果使用async修饰符声明的方法返回缓存结果或同步完成,则额外分配可能会成为性能关键代码段中的重要时间成本。 如果这些分配发生在紧密的循环中,它可能会变得非常昂贵。 新语言function意味着除了Task , Task和void之外,异步方法可以返回其他类型。 返回的类型仍必须满足异步模式,这意味着必须可以访问GetAwaiter方法。 作为一个具体示例,ValueTask类型已添加到.NET框架中以使用此新语言function: 这听起来不错,但我不能为我的生活找到任何不仅仅使用库存ValueTask类型的ValueTask 。 我想制作类似自己的任务类型。 具体来说,我想要一个行为类似于Task ,但具有更多function的error handling方式。 这是我在项目中用于functionerror handling的类型: public class Try { public T Data { get; } public Exception Error { get; } public bool HasData => Error == null; public bool HasError => Error != null; public Try(T data) { Data = data; […]

aync与异步方法中的Task.Result

执行以下操作之间的区别是什么: async Task method(){ var r = await dynamodb.GetItemAsync(…) return r.Item; } VS async Task method(){ var task = dynamodb.GetItemAsync(…) return task.Result.Item; } 在我的情况下由于某种原因只有第二个工作。 第一个似乎永远不会结束。

缓存异步操作

我正在寻找一种缓存异步操作结果的优雅方法。 我首先有一个像这样的同步方法: public String GetStuff(String url) { WebRequest request = WebRequest.Create(url); using (var response = request.GetResponse()) using (var sr = new StreamReader(response.GetResponseStream())) return sr.ReadToEnd(); } 然后我让它异步: public async Task GetStuffAsync(String url) { WebRequest request = WebRequest.Create(url); using (var response = await request.GetResponseAsync()) using (var sr = new StreamReader(response.GetResponseStream())) return await sr.ReadToEndAsync(); } 然后我决定我应该缓存结果,所以我不需要经常在外面查询: ConcurrentDictionary _cache […]

HttpClient(C#)在许多异步请求上失败了吗?

我正在使用HttpClient异步向外部api发出许多请求。 我等待所有请求完成,然后在其他代码中使用响应。 我的问题是,如果我发出太多请求,当我使用Task.WhenAll等待时,我的代码会引发exception。 这段代码最终将并行运行,我的意思是我将同时执行多组这些异步请求(即10组200个异步请求)。 我已经实例化了一个HttpClient,我正在使用.NET 4.5异步/等待修饰符,如下所示: using (var client = new HttpClient()) { // make a list of tasks List<Task> taskList; List replies; for (int i = 0; i < MAX_NUMBER_REQUESTS; i++) { taskList.Add(client.GetAsync(externalUri); } List responses = await Task.WhenAll(taskList); // read each response after they have returned foreach (var response in responses) { var […]

Parallel.Invoke不等待异步方法完成

我有一个应用程序从不同的来源提取相当数量的数据。 本地数据库,网络数据库和Web查询。 任何这些都可能需要几秒钟才能完成。 所以,首先我决定并行运行这些: Parallel.Invoke( () => dataX = loadX(), () => dataY = loadY(), () => dataZ = loadZ() ); 正如预期的那样,所有三个并行执行,但是在最后一个块完成之前,整个块上的执行都不会返回。 接下来,我决定在应用程序中添加一个微调器或“忙指示器”。 我不想阻止UI线程或者微调器不会旋转。 所以这些需要在async模式下运行。 但是如果我在异步模式下运行所有​​三个,那么它们的影响就会“同步”发生,而不是与UI在同一个线程中。 我仍然希望他们并行运行。 spinner.IsBusy = true; Parallel.Invoke( async () => dataX = await Task.Run(() => { return loadX(); }), async () => dataY = await Task.Run(() => { return loadY(); }), […]

等待Task.Factory.StartNew(()=>与Task.Start;等待任务;

这两种使用等待forms之间是否有任何function差异? string x = await Task.Factory.StartNew(() => GetAnimal(“feline”)); Task myTask = new Task(() => GetAnimal(“feline”)); myTask.Start(); string z = await myTask; 具体来说,在1中调用每个操作的顺序是什么? 是StartNew被调用然后等待调用,还是等待在1中首先调用?

异步并行下载文件

编辑 我已经改变了问题的标题,以反映我的问题,但也回答了如何轻松实现这一目标。 我试图让第二种方法返回Task而不是第一种方法中的Task ,但是由于尝试修复它,我得到了一连串的错误。 我在await body(partition.Current);之前添加了return await body(partition.Current); 反过来它要求我在下面添加一个return语句,所以我在下面添加了return null 但是现在select语句抱怨它无法从查询中推断出类型参数 我将Task.Run更改为Task.Run但没有成功。 我该如何解决? 第一种方法来自http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx ,第二种方法是我正在尝试创建的重载。 public static class Extensions { public static Task ForEachAsync(this IEnumerable source, int dop, Func body) { return Task.WhenAll( from partition in Partitioner.Create(source).GetPartitions(dop) select Task.Run(async delegate { using (partition) while (partition.MoveNext()) await body(partition.Current); })); } public static Task ForEachAsync(this IEnumerable source, […]

在.Net native中的线程池上运行异步任务的性能很差

我发现托管vs .Net本机代码有一个奇怪的区别。 我有一个繁重的工作重定向到线程池。 当在托管代码中运行应用程序时,一切都运行顺畅,但是一旦我打开本机编译 – 任务运行速度慢几十倍,以至于它挂起UI线程(我猜CPU是如此过载)。 以下是调试输出的两个屏幕截图,左侧的屏幕截图来自托管代码,右侧的屏幕截图来自本机编译。 正如您所看到的,UI任务所消耗的时间在两种情况下几乎相同,直到启动线程池作业时 – 然后在托管版本中UI经过的时间增长(实际上UI被阻止而您无法采取任何操作)。 线程池工作的时间不言自明。 重现问题的示例代码: private int max = 2000; private async void UIJob_Click(object sender, RoutedEventArgs e) { IProgress progress = new Progress((p) => { MyProgressBar.Value = (double)p / max; }); await Task.Run(async () => { await SomeUIJob(progress); }); } private async Task SomeUIJob(IProgress progress) { Stopwatch watch […]

异步方法返回null

如果我尝试模拟包含async方法的类型,例如: interface Foo { Task Bar(); } 然后mock的Bar方法返回null。 我猜Moq选择default(Task)作为我的方法的默认返回值,这确实是null 。 但是,Moq应该选择像Task.FromResult(default(int))这样的默认值。 我可以强制Moq使异步方法返回非空任务吗?