Tag: async await

始终在Windows服务上运行线程

我正在编写一个Windows服务,它将启动多个工作线程,这些线程将监听Amazon SQS队列并处理消息。 将有大约20个线程监听10个队列。 线程必须始终运行,这就是为什么我倾向于实际使用实际线程作为工作循环而不是线程池线程。 这是一个顶级实现。 Windows服务将启动多个工作线程,每个线程都会监听它的队列和进程消息。 protected override void OnStart(string[] args) { for (int i = 0; i < _workers; i++) { new Thread(RunWorker).Start(); } } 这是工作的实施 public async void RunWorker() { while(true) { // .. get message from amazon sqs sync.. about 20ms var message = sqsClient.ReceiveMessage(); try { await PerformWebRequestAsync(message); await InsertIntoDbAsync(message); } […]

RunAsync – 如何等待UI线程上的工作完成?

等待Dispatcher.RunAsync时,将在计划工作时进行继续,而不是在工作完成时进行。 我怎么能等待完成的工作? 编辑 我的原始问题假设过早延续是由API的设计引起的,所以这是真正的问题。 在使用异步委托等待Dispatcher.RunAsync ,在委托代码中使用await时,会在遇到await时发生延续,而不是在工作完成时。 我怎么能等待完成的工作? 编辑2 您可能需要分派已经在UI线程上工作的一个原因是解决细微的时序和布局问题。 对于视觉树中的元素的大小和位置的值来说,通常是非常常见的,并且用于稍后的UI迭代的调度工作可以帮助。

使用ASP.NET Web API,我的ExecutionContext没有流入异步操作

我很难理解ExecutionContext背后的机制。 从我在线阅读的内容来看,安全性(Thread Principal),文化等上下文相关的项目应该跨越执行工作单元的边界内的异步线程。 我遇到了非常令人困惑和潜在危险的错误。 我注意到我的线程的CurrentPrincipal在异步执行中丢失了。 以下是ASP.NET Web API方案的示例: 首先,让我们设置一个简单的Web API配置,其中包含两个委托处理程序以进行测试。 他们所做的只是写出调试信息并传递请求/响应,除了第一个“DummyHandler”,它设置线程的主体以及要在整个上下文中共享的数据(请求的相关ID)。 public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MessageHandlers.Add(new DummyHandler()); config.MessageHandlers.Add(new AnotherDummyHandler()); config.Routes.MapHttpRoute( name: “DefaultApi”, routeTemplate: “api/{controller}/{id}”, defaults: new { id = RouteParameter.Optional } ); } } public class DummyHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { […]

超时使用TaskCompletionSource实现的异步方法

我有一个blackbox对象,它暴露了一个异步操作的方法,并在操作完成时触发一个事件。 我已经使用TaskCompletionSource将其包装到Task BlackBoxOperationAysnc()方法中 – 效果很好。 但是,在那个异步包装器中,如果在给定的超时后没有收到事件,我想管理用超时错误完成异步调用。 目前我使用计时器管理它: public Task BlackBoxOperationAysnc() { var tcs = new TaskCompletionSource(); const int timeoutMs = 20000; Timer timer = new Timer(_ => tcs.TrySetResult(OpResult.Timeout), null, timeoutMs, Timeout.Infinite); EventHandler eventHandler = (sender, args) => { … tcs.TrySetResult(OpResult.BlarBlar); } blackBox.EndAsyncOpEvent += eventHandler; blackBox.StartAsyncOp(); return tcs.Task; } 这是管理超时的唯一方法吗? 有没有设置我自己的计时器 – 我看不到TaskCompletionSource内置的任何超时?

异步CTP – 如何使用async / await来调用wcf服务?

如果我调用WCF服务方法,我会这样做: proxy.DoSomethingAsync(); proxy.DoSomethingAsyncCompleted += OnDoSomethingAsyncCompleted; 我怎么能使用新的async ctp做同样的事情? 我想我需要像proxy.DoSomethingTaskAsync或proxy.DoSomethingAsync().ToTask() ? Web服务调用需要返回一个Task才能使用await关键字,但是如何?

Async / Await与WinForms ProgressBar

我已经使用BackgroundWorker在过去使用过这种类型的东西,但我想使用.NET 4.5的新异步/等待方法。 我可能正在咆哮错误的树。 请指教。 目标 :创建一个组件,该组件将执行一些长时间运行的工作,并在执行工作时显示带有进度条的模态表单。 该组件将获取窗口的句柄,以便在执行长时间运行的工作时阻止交互。 状态 :请参阅下面的代码。 在我尝试与windows进行交互之前,我认为自己做得很好。 如果我把事情单独处理(即不要触摸!),一切都“完美”运行,但是如果我点击任一窗口,那么程序会在长时间运行结束后挂起。 忽略实际交互(拖动),就像UI线程被阻止一样。 问题 :我的代码可以很容易修复吗? 如果是这样,怎么样? 或者,我应该使用不同的方法(例如BackgroundWorker)吗? 代码 (Form1是带有ProgressBar和公共方法的标准表单,UpdateProgress,用于设置ProgressBar的值): using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Console.WriteLine(“Starting..”); var mgr = new Manager(); mgr.GoAsync(); Console.WriteLine(“..Ended”); Console.ReadKey(); } } class Manager { private static […]

Async / Await使用Task.Run异步启动新线程吗?

我已经阅读了很多文章,但仍然无法理解这一部分。 考虑以下代码: private async void button1_Click(object sender, EventArgs e) { await Dosomething(); } private async Task Dosomething() { await Task.Run((() => “Do Work”)); return “I am done”; } 第一个问题: 当我单击按钮时,它将调用DoSomething并等待通过调用Task.Run(如果我没有记错)从线程池创建线程的任务,并且所有这些都以异步方式运行。 所以我实现了创建一个完成我的工作但是异步执行的线程? 但是考虑到我不需要任何结果,我只是希望在没有得到任何结果的情况下完成工作,是否真的需要使用async / await,如果是这样,怎么样? 第二个问题: 在异步运行线程时,它是如何工作的? 它是在主UI上运行但是在单独的线程上运行还是在单独的线程上运行并且在该方法中是异步的?

在Windows服务中执行任务循环的最佳方法

我有一种方法可以向我们的客户发送一些短信,如下所示: public void ProccessSmsQueue() { SmsDbContext context = new SmsDbContext(); ISmsProvider provider = new ZenviaProvider(); SmsManager manager = new SmsManager(context, provider); try { manager.ProcessQueue(); } catch (Exception ex) { EventLog.WriteEntry(ex.Message, EventLogEntryType.Error); } finally { context.Dispose(); } } protected override void OnStart(string[] args) { Task.Factory.StartNew(DoWork).ContinueWith( ??? ) } 所以,我有一些问题: 我不知道方法运行需要多长时间; 该方法可以抛出exception,我想在EventLog上编写 我希望每10分钟在循环中运行此方法, 但只能在最后一次执行完成后运行。 我怎么能做到这一点? 我想过使用ContinueWith() ,但我仍然对如何构建整个逻辑有疑问。

entity framework设计器首先将导航属性作为任务获取

任务模式说,为了保持一致,一切都必须完全异步或完全不同步。 首先使用实体​​框架设计器,我可以很容易地实现这一点 var course = await db.Courses.FindAsync(CourseID); 课程是由entity framework生成的DbSet,因此具有所有Async方法。 问题是,如果我向该类添加导航属性,后者不是DbSet,并且它不包含任何异步方法定义。 例如,如果我将导航属性添加到Students表,它将被创建为虚拟ICollection学生,这意味着我无法使用异步方法。 但我真正想要的是拥有entity framework来自动生成Task ,以便能够等待导航属性。 可能吗? 我的目标是实现这样的目标: var course = await db.Courses.FindAsync(CourseID); var student = await course.Students.FindAsync(StudentID); 而目前我的选择是混合async / notAsync代码: var course = await db.Courses.FindAsync(CourseID); var student = course.Students.First(p => p.ID = StudentID); 或根本不使用导航属性: var course = await db.Courses.FindAsync(CourseID); var student = await db.Students.Where(p => p.CourseID […]

异步设置Thread.CurrentPrincipal?

使用ASP.NET WebAPI,在身份validation期间,设置Thread.CurrentPrincipal ,以便控制器稍后可以使用ApiController.User属性。 如果该身份validation步骤变为异步(以咨询另一个系统),则会丢失CurrentPrincipal任何突变(当调用者await恢复同步上下文时)。 这是一个非常简化的示例(在实际代码中,身份validation发生在动作filter中): using System.Diagnostics; using System.Security.Principal; using System.Threading; using System.Threading.Tasks; public class ExampleAsyncController : System.Web.Http.ApiController { public async Task GetAsync() { await AuthenticateAsync(); // The await above saved/restored the current synchronization // context, thus undoing the assignment in AuthenticateAsync(). Debug.Assert(User is GenericPrincipal); } private static async Task AuthenticateAsync() { // Save the […]