Tag: async await

C#在同步上下文中运行异步任务

我没有太多C#异步经验。 任务 – 从互联网加载位图。 之前,我只是逐个加载它们,同步。 将它们加载到异步中可以更快地获得结果。 在下面,我做了两个例子,我如何获得单个图像 – GetImage和GetImageAsync 。 对于图像列表,我将使用LoadImages和LoadImages2 。 LoadImages将在异步中运行同步函数(所有这些都在同一时间(?)), LoadImages2将在异步中运行异步函数并产生相同的结果(?)。 我不完全理解的事情 – 在GetImageAsync await request.GetResponseAsync() 。 我真的需要它吗? 做同样的事情是一种“更好”的方式吗? LoadImages和LoadImages2之间是否存在任何差异? 目前,我正在考虑选择LoadImages和LoadImages选项。 另外,我不想用async Task装饰每个函数,我只需要在异步中加载这些图像。 public Bitmap GetImage(string url) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; using (WebResponse response = request.GetResponse()) using (Stream responseStream = response.GetResponseStream()) return new Bitmap(responseStream); } public async Task GetImageAsync(string […]

Async / Await等同于.ContinueWith和CancellationToken以及TaskScheduler.FromCurrentSynchronizationContext()调度程序

这是这个问题的后续行动。 问题 :使用async / await而不是.ContinueWith()来表达以下内容的简洁方法是什么?: var task = Task.Run(() => LongRunningAndMightThrow()); m_cts = new CancellationTokenSource(); CancellationToken ct = m_cts.Token; var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task updateUITask = task.ContinueWith(t => UpdateUI(t), ct, TaskContinuationOptions.None, uiTaskScheduler); 我主要对UI SynchronizationContext的情况感兴趣(例如对于Winforms) 请注意,该行为具有以下所有期望的行为: 当CancellationToken被取消时, updateUITask最终会被取消(即LongRunningAndMightThrow工作可能仍会持续很长时间)。 在运行UpdateUI lambda之前, 在UI线程上检查ct CancellationToken是否取消(请参阅此答案 )。 在task完成或出现故障的某些情况下, updateUITask最终会被取消(因为在执行UpdateUI lambda之前在UI线程上检查了ct CancellationToken。 在UI线程上检查CancellationToken和UpdateUI lambda的运行之间没有中断。 也就是说,如果只在UI线程上取消了CancellationTokenSource ,那么在检查CancellationToken和运行UpdateUI lambda之间没有竞争条件 – 没有什么可以在这两个事件之间触发CancellationToken ,因为UI线程在这两个事件之间没有放弃。 讨论: […]

KeyVault GetSecretAsync永远不会返回

在Web应用程序中使用KeyVault的示例代码中包含以下代码: public static async Task GetSecret(string secretId) { var secret = await keyVaultClient.GetSecretAsync(secretId); return secret.Value; } 我已将示例中包含的KeyVaultAccessor对象合并到我的应用程序中以进行测试。 该调用作为对我的一个web api控制器方法的查询的一部分执行: var secret = KeyVaultAccessor.GetSecret(“https://superSecretUri”).Result; 不幸的是,调用永远不会返回,查询将无限期地挂起…… 可能是什么原因,因为坦率地说我不知道​​从哪里开始……?

在Windows 8应用程序中扩展启动后无法导航到页面

我已经按照Microsoft提供的指南创建了扩展的启动画面。 屏幕显示关闭,数据加载,但随后应用程序无法导航到登录页面。 这怎么可能? ExtendedSplash.xaml.cs public sealed partial class ExtendedSplash { public ExtendedSplash(SplashScreen splash) { this.InitializeComponent(); // Position the extended splash screen image in the same location as the splash screen image. this.extendedSplashImage.SetValue(Canvas.LeftProperty, splash.ImageLocation.X); this.extendedSplashImage.SetValue(Canvas.TopProperty, splash.ImageLocation.Y); this.extendedSplashImage.Height = splash.ImageLocation.Height; this.extendedSplashImage.Width = splash.ImageLocation.Width; // Position the extended splash screen’s progress ring. this.ProgressRing.SetValue(Canvas.TopProperty, splash.ImageLocation.Y + splash.ImageLocation.Height + 32); […]

非阻塞和重复发生的生产者/消费者通知者实施

搜索了一段代码,它做了我想要的,我很满意。 读这个 , 这有很大帮助。 我有一个场景,我需要单个消费者在新数据可用时通知单个生产者,但也希望定期通知消费者,无论新数据是否可用。 如果通知消费者的时间超过了重复发生的时间,那就没有问题,但不应该频繁通知消费者。 当消费者已经通知并正在工作时,可能会发生“新数据”的多个通知。 (所以SemaphoreSlim不太适合)。 因此,比生产者通知速率慢的消费者不会排队后续通知,他们只是“重新发信号通知”相同的“数据可用”标志而没有影响。 我还希望消费者异步等待通知(不阻塞线程)。 我已经将下面的类包裹在一起,它包含了TaskCompletionSource并且还使用了一个内部Timer。 public class PeriodicalNotifier : IDisposable { // Need some dummy type since TaskCompletionSource has only the generic version internal struct VoidTypeStruct { } // Always reuse this allocation private static VoidTypeStruct dummyStruct; private TaskCompletionSource internalCompletionSource; private Timer reSendTimer; public PeriodicalNotifier(int autoNotifyIntervalMs) { internalCompletionSource = […]

entity framework5线程敏捷性

抛出EntityFramework代码内部的NullReferenceException(EF bug?),但我的问题是关于Entity Framework(v5)和WebAPI异步控制器动作。 一个repro很难在这里重新创建,但代码本质上做了以下事情: public class AController : ApiController { private IUow _uow; //among other things, a DbContext // DI ctor public AController(IUow uow) { _uow = uow; } [HttpPost] public async Task Post(Model model) { Entity e = _uow.Entity.GetById(model.id); await IO_Ops_Async(model); new ModelAdapter().UpdateEntity(entity, model); _uow.Commit(); <- EXCEPTION THROWN DURING THIS CALL – see below […]

异步正则表达式是否存在于C#中,它们会帮助我的情况吗?

我的应用程序使用regex并行搜索多个文件, await Task.WhenAll(filePaths.Select(FindThings)); 在FindThings内部,它花费大部分时间执行正则表达式搜索,因为这些文件的大小可能达到数百mb。 static async Task FindThings(string path) { string fileContent = null; try { using (var reader = File.OpenText(path)) fileContent = await reader.ReadToEndAsync(); } catch (Exception e) { WriteLine(lineIndex, “{0}: Error {1}”, filename, e); return; } var exitMatches = _exitExp.Matches(fileContent); foreach (Match exit in exitMatches) { if (_taskDelay > 0) await Task.Delay(_taskDelay); // […]

调用异步方法时使用.Wait()的情况是什么

我的asp.net mvc-5 Web应用程序中有以下async长时间运行方法: – public async Task ScanAsync(string FQDN) { // sample of the operation i am doing var c = await context.SingleOrDefaultAsync(a=>a.id == 1); var list = await context.Employees.ToListAsync(); await context.SaveChangesAsync(); //etc.. } 我正在使用支持运行后台作业的Hangfire工具来及时调用此异步方法,但不幸的是,hangefire工具不支持直接调用异步方法。 所以为了克服这个问题,我创建了上述方法的同步版本,如下: – public void Scan() { ScanAsync(“test”).Wait(); } 然后从HangFire调度程序我调用sync方法如下: – RecurringJob.AddOrUpdate(() => ss.Scan(), Cron.Minutely); 所以我知道使用.Wait()将主要在方法执行期间占用iis线程,但正如我所提到的,我需要这样做,因为我无法在hangefire调度程序中直接调用异步TASK。 那么当我使用.Wait()调用异步方法时会发生什么?整个方法的操作是否会以同步方式完成? 例如,如上所示,我在ScanAsync()有三个异步操作; SingleOrDefualtAsync , ToListAsync和SaveChangesAsync […]

全局捕获在后台线程中从WCF异步调用抛出的exception

我有一个与WCF服务通信的WPF应用程序。 我正在使用以下基于async的模式从我的ViewModel调用我的WCF服务(我正在使用MVVM模式): public async override void MyCommandImplementation() { using (var proxy = new MyProxy()) { var something = await proxy.GetSomethingAsync(); this.MyProperty = something; } } 当我遵循MVVM模式时,我有我的ViewModel公开的ICommand公共属性,因此关联的命令实现不会返回Task对象,因为它们就像事件处理程序一样。 所以exception处理实际上非常简单,即我能够使用以下模式捕获从我的WCF服务抛出的任何exception: public async override void MyCommandImplementation() { try { using (var proxy = new MyProxy()) { var something = await proxy.GetSomethingAsync(); } } catch (FaultException ex) { // Do […]

异步SQL查询执行 – Task.WaitAll(tasks)永远不会完成

我有一个应用程序使用异步查询执行将数据从MS SQL服务器移动到MySQL服务器; 数据移动正常,但RunAllTask​​s()方法中的Task.WaitAll(任务)调用永远不会完成。 异步任务都遵循PumpLocsAsync()的模式,其中通过BeginExecuteReader异步调用对MS SQL的调用; 当读者返回结果时,MySQL会正常插入。 .. async Task PumpLocsAsync() { using (var conn = new SqlConnection(SqlConnStr)) using (var cn = new MySqlConnection(MysqlConnStr)) using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = “SELECT HERE”; conn.Open(); var handle = cmd.BeginExecuteReader(); await Task.Factory.FromAsync(handle, (ar) => { var rdr = cmd.EndExecuteReader(ar); var qry = @”INSERT […]