Tag: 异步

C#异步方法仍然挂起UI

我有这两种方法,我想运行异步以保持UI响应。 但是,它仍然悬挂着UI。 有什么建议? async void DoScrape() { var feed = new Feed(); var results = await feed.GetList(); foreach (var itemObject in results) { var item = new ListViewItem(itemObject.Title); item.SubItems.Add(itemObject.Link); item.SubItems.Add(itemObject.Description); LstResults.Items.Add(item); } } public class Feed { async public Task<List> GetList() { var client = new WebClient(); string content = await client.DownloadStringTaskAsync(new Uri(“anyUrl”)); var lstItemObjects […]

C#中基于任务的异步方法的超时模式

据我所知,有两种可能的模式来实现基于任务的异步方法的超时: 内置超时 public Task DoStuffAsync(TimeSpan timeout) 这种方法难以实现,因为实现整个调用堆栈的全局超时并不容易。 例如,Web API控制器接收HTTP请求并调用DoStuffAsync ,调用者希望全局超时为3秒。 也就是说,每个内部异步方法调用都需要接收已经使用过的时间的减法… 没有内置超时 public Task DoStuffAsync(CancellationToken cancellationToken) ………. CancellationTokenSource cancellationSource = new CancellationTokenSource(); Task timeoutTask = Task.Delay(3000); if(await Task.WhenAny(DoStuffAsync(cancellationTokenSource), timeoutTask) == timeoutTask) { cancellationSource.Cancel(); throw new TimeoutException(); } 这似乎是最可靠和易于实现的模式。 第一个调用者定义全局超时,如果超时 ,则将取消所有挂起的操作。 此外,它为直接调用者提供取消令牌,内部调用将共享相同的取消令牌引用。 因此,如果最高调用者超时,它将能够取消任何工作线程。 整个问题 有没有我缺少的模式,或者如果我使用no内置超时开发API,我是否正确?

如何限制c#中的最大并行任务数

我有一个1000输入消息的集合来处理。 我正在循环输入集合并为每个消息启动新任务以进行处理。 //Assume this messages collection contains 1000 items var messages = new List(); foreach (var msg in messages) { Task.Factory.StartNew(() => { Process(msg); }); } 我们可以猜测当时同时处理多少个最大消息(假设是普通的四核处理器),还是我们可以限制当时要处理的最大消息数? 如何确保以与Collection相同的顺序/顺序处理此消息?

以非阻塞方式调用TaskCompletionSource.SetResult

我发现了TaskCompletionSource.SetResult(); 在返回之前调用等待任务的代码。 在我的情况下,导致死锁。 这是一个在普通Thread启动的简化版本 void ReceiverRun() while (true) { var msg = ReadNextMessage(); TaskCompletionSource task = requests[msg.RequestID]; if(msg.Error == null) task.SetResult(msg); else task.SetException(new Exception(msg.Error)); } } 代码的“异步”部分看起来像这样。 await SendAwaitResponse(“first message”); SendAwaitResponse(“second message”).Wait(); Wait实际上嵌套在非异步调用中。 SendAwaitResponse(简化) public static Task SendAwaitResponse(string msg) { var t = new TaskCompletionSource(); requests.Add(GetID(msg), t); stream.Write(msg); return t.Task; } 我的假设是第二个SendAwaitResponse将在ThreadPool线程中执行,但它会在为ReceiverRun创建的线程中继续。 无论如何设置任务的结果而不继续等待代码? 该应用程序是一个控制台应用程

使用async和await关键字的好处

我是C#中异步方法的新手。 我已经读过这些关键字async并await帮助通过异步某些方法使程序更具响应性。 我有这个片段: 第一道路 public static void Main() { Console.WriteLine(“Hello!! welcome to task application”); Console.ReadKey(); Task ourtask = Task.Factory.StartNew(() => { return “Good Job”; }); ourtask.Wait(); Console.WriteLine(ourtask.Result); Console.ReadKey(); } 第二种方式 public static void Main() { Launch(); } public static async void Launch() { Console.WriteLine(“Hello!! welcome to task application”); Console.ReadKey(); Console.WriteLine(await GetMessage()); Console.ReadKey(); } public static […]

由非托管应用程序托管的托管组件中的Await和SynchronizationContext

[EDITED] 这似乎是 Framework的Application.DoEvents实现中的一个错误 ,我在这里报告过 。 在UI线程上恢复错误的同步上下文可能会严重影响像我这样的组件开发人员。 赏金的目标是更多地关注这个问题并奖励@MattSmith,他的答案帮助追踪它。 我负责通过COM互操作将基于.NET WinForms UserControl的组件作为ActiveX暴露给传统的非托管应用程序 。 运行时要求是.NET 4.0 + Microsoft.Bcl.Async。 该组件被实例化并在应用程序的主要STA UI线程上使用。 它的实现使用async/await ,因此它期望在当前线程(即WindowsFormsSynchronizationContext )上安装序列化同步上下文的实例。 通常, WindowsFormsSynchronizationContext由Application.Run设置,这是托管应用程序的消息循环运行的地方。 当然, 这不是非托管主机应用程序的情况 ,我无法控制它。 当然,主机应用程序仍然有自己的经典Windows消息循环,因此序列化await延续回调应该不是问题。 然而,到目前为止我提出的解决方案都不是完美的,甚至都不能正常工作。 这是一个人为的例子,主机app调用Test方法: Task testTask; public void Test() { this.testTask = TestAsync(); } async Task TestAsync() { Debug.Print(“thread before await: {0}”, Thread.CurrentThread.ManagedThreadId); var ctx1 = SynchronizationContext.Current; Debug.Print(“ctx1: {0}”, ctx1 != […]

什么是异步和等待,何时在Windows开发中使用这些?

我总是看到Silverlight中使用的关键字async,但是想知道是否有人对虚拟对象的解释是什么以及何时使用它及其好处。 如果你能解释,请大家好评。 谢谢。

在ASP.NET MVC中检测异步客户端断开连接

给定一个异步控制器: public class MyController : AsyncController { [NoAsyncTimeout] public void MyActionAsync() { … } public void MyActionCompleted() { … } } 假设MyActionAsync开始需要几分钟的过程。 如果用户现在转到MyAction操作,浏览器将等待连接打开。 如果用户关闭其浏览器,则关闭连接。 是否有可能检测到服务器上发生的情况(最好是在控制器内)? 如果是这样,怎么样? 我已经尝试重写OnException但在这种情况下永远不会触发。 注意:我非常感谢下面的有用答案,但这个问题的关键方面是我正在使用AsyncController 。 这意味着HTTP请求仍然是打开的 (它们像COMET或BOSH一样长寿),这意味着它是一个实时套接字连接。 为什么在此实时连接终止时(即“通过对等方重置连接”,TCP RST数据包)不能通知服务器?

Task.Run和UI进度更新

此代码段来自Stephen Cleary的博客,并提供了使用Task.Run时如何报告进度的示例。 我想知道为什么没有更新UI的交叉线程问题,我的意思是为什么不需要调用? private async void button2_Click(object sender, EventArgs e) { var progressHandler = new Progress(value => { label2.Text = value; }); var progress = progressHandler as IProgress; await Task.Run(() => { for (int i = 0; i != 100; ++i) { if (progress != null) progress.Report(“Stage ” + i); Thread.Sleep(100); } }); label2.Text = […]

从Windows窗体异步执行存储过程然后断开连接?

我从我的应用程序调用存储过程,可能需要30分钟才能执行。 我不想让我的用户在整个时间段内打开应用程序。 所以我想打电话给sproc,让它飞起来,让他们关闭应用程序然后再回来。 我怎样才能做到这一点?