Tag: 异步

明确地实现IAsyncResult

我一般都对部分实现接口持谨慎态度。 但是, IAsyncResult有点特殊情况,因为它支持几种截然不同的使用模式。 使用/看到使用AsyncState / AsyncCallback模式的AsyncState是AsyncState ,而不是只使用AsyncWaitHandle调用EndInvoke ,或者轮询IsCompleted ( AsyncWaitHandle )? 相关问题: 检测ThreadPool WorkItem是否已完成/等待完成 。 考虑这个类(非常近似,需要锁定): public class Concurrent { private ManualResetEvent _resetEvent; private T _result; public Concurrent(Func f) { ThreadPool.QueueUserWorkItem(_ => { _result = f(); IsCompleted = true; if (_resetEvent != null) _resetEvent.Set(); }); } public WaitHandle WaitHandle { get { if (_resetEvent == […]

异步套接字读取:不能退出启动线程 – 该怎么办?

我有一个我异步读取的NetworkStream(使用async / await) await Task.Factory.FromAsync((cb, state) => stream.BeginRead(buffer, offset, readLen – offset), stream.EndRead, null); 不幸的是,有时会发生ioexception:“由于线程退出或应用程序请求,I / O操作已中止。” 我相信我达到了Socke.EndReceive中记录的要求: http : //msdn.microsoft.com/en-us/library/w7wtt64b.aspx 。 哪个州: 当该线程退出时,由给定线程启动的所有I / O都将被取消。 如果线程在操作完成之前退出,则挂起的异步操作可能会失败。 由于异步方法在默认调度程序上运行,因此无法保证此要求。 有没有解决的办法? 我是否需要启动专用线程来启动I / O? 最好的问候,德克

UDP服务器中接收数据包的连接重置

我正在研究一个服务器应用程序(C#,.NET 4.0),它需要每秒处理数千个UDP数据包。 所以我决定使用SocketAsyncEventArg来实现服务器。 我面临的问题是我的实现只收到一个数据包然后我得到“ConnectionReset”错误(我从未想过我会得到这个错误,因为UDP是无连接的)。 这是我的测试实现: using System; using System.Net; using System.Net.Sockets; static class Program { static void Main(string[] args) { UdpEchoServer.Start(); while (true) { Console.ReadLine(); SendPacket(); } } static void SendPacket() { Console.WriteLine(“SendPacket”); var c = new UdpClient(); c.Send(new byte[5], 5, new IPEndPoint(IPAddress.Parse(“127.0.0.1”), 445)); c.Close(); } } static class UdpEchoServer { static Socket mSocket; static […]

System.Diagnostics.Process.Start奇怪的行为

我正在编写一个应用程序来启动和监视C#中的其他应用程序。 我正在使用System.Diagnostics.Process类来启动应用程序,然后使用Process.Responding属性监视应用程序,以每100毫秒轮询一次应用程序的状态。 我使用Process.CloseMainWindow来停止应用程序或Process.Kill如果它没有响应就杀死它。 我注意到一种奇怪的行为,有时进程对象进入一种状态,即当底层进程在循环中挂起并且它不响应CloseMainWindow时,响应属性总是返回true。 重现它的一种方法是在启动流程实例后立即轮询Responding属性。 所以举个例子 _process.Start(); bool responding = _process.Responding; 将重现错误状态 _process.Start(); Thread.Sleep(1000); bool responding = _process.Responding; 将工作。 将睡眠周期减少到500将再次引入错误状态。 启动后调用_process.Responding太快的东西似乎阻止了对象获取正确的Windows消息队列处理程序。 我想我需要等待_process.Start完成它的异步工作。 有没有比调用Thread.Sleep更好的方法来等待它? 我不太自信1000毫秒总是足够的。

如何阻止异步tcp .NET代码耗尽整个系统的资源

在我的一些异步tcp服务器代码中,偶尔会发生错误,导致进程占用整个系统的内存。 在查看日志,事件查看器和一些MS文档时,如果“调用应用程序多次向同一客户端调用异步IO,那么如果远程客户端停止其结束,您可能会看到堆碎片和私有字节增加” / O“导致内存使用量激增以及System.Threading.OverlappedData结构和字节数组的固定。 知识库文章提出的解决方案是“设置未完成缓冲区(发送或接收)与其异步IO的上限。” 怎么做到这一点? 这是指发送到BeginRead的byte []吗? 那么解决方案只是用信号量包装访问byte []? 编辑:信号量控制访问字节缓冲区或只是具有静态大小的字节缓冲池是两种常见的解决方案。 我仍然存在的一个问题是,当这个异步客户端问题发生时(实际上它可能是一些奇怪的网络事件)有信号量或字节缓冲池将阻止我耗尽内存,但它无法解决问题。 我的缓冲池可能会被问题客户端吞噬,实际上锁定了正确的函数合法客户端。 编辑2:遇到了这个伟大的答案 。 基本上它显示了如何手动取消固定对象。 虽然异步TCP代码可以固定到幕后运行时规则,但是可以通过在使用前明确地固定每个缓冲区来覆盖它,然后在块的末尾或者在finally中取消固定。 我现在想弄明白……

两种通过SmtpClient异步发送电子邮件的方式,结果不同

这里简单的概念。 这适用于使用MVC 3和Entity Framework 4构建的站点。用户在站点上注册后,会向其电子邮件地址发送一封电子邮件。 我首先使用SmtpClient.Send()实现它,它工作正常。 然后我明白了尝试异步发送电子邮件。 我遇到了我尝试过的两种异步方法的问题。 首次实施(来自这篇未回答的post: https : //stackoverflow.com/questions/7558582/how-to-dispose-using-smtpclient-send-and-asynccallback ): public bool Emailer(){ . . . using (var smtpClient = new SmtpClient()) { smtpClient.EnableSsl = true; smtpClient.Host = “smtp.gmail.com”; smtpClient.Port = 587; smtpClient.UseDefaultCredentials = false; smtpClient.Credentials = new NetworkCredential(“myaddress@gmail.com”, “mypassword”); var sd = new SendEmailDelegate(smtpClient.Send); var cb = new AsyncCallback(SendEmailResponse); sd.BeginInvoke(message, cb, […]

在控制台应用程序中使用async / await时,为什么需要AsyncContext?

我在我的控制台应用程序中调用异步方法。 我不希望应用程序在启动后立即退出,即在等待完成任务之前。 好像我可以这样做: internal static void Main(string[] args) { try { Task.WaitAll(DoThisAsync()); } catch (Exception ex) { Console.Error.WriteLine(ex); throw; } } internal static async Task DoThisAsync() { //… } 但根据Stephen Cleary的文章 ,似乎我不能这样做,而应该创建某种上下文,让async在完成后返回(例如AsyncContext )。 上面的代码可以工作,它在Task.WaitAll(DoThisAsync());之后返回主线程Task.WaitAll(DoThisAsync()); ,那么为什么我需要使用自定义上下文?

如何在不关闭流的情况下取消NetworkStream.ReadAsync

我试图使用NetworkStream.ReadAsync()来读取数据,但我无法找到如何在调用时取消ReadAsync()。 对于后台,NetworkStream由连接的BluetoothClient对象(来自32Feet.NET蓝牙库)提供给我。 我正在尝试的当前get-it-working代码如下。 int bytesRead; while (this.continueReading) { bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length); Console.WriteLine(“Received {0} bytes”, bytesRead); } Console.WriteLine(“Receive loop has ended”); 代码可以很好地接收数据,并且如果continueReading标志设置为false并且接收到数据,则将停止循环,但是在接收到数据之前,它将不会继续通过ReadAsync()行。 我无法看到如何在不接收数据的情况下中止呼叫。 我知道ReadAsync有一个重载提供了一个CancellationToken,但是由于NetworkStream没有覆盖默认的ReadAsync行为,所以会忽略该令牌(请参阅带有取消令牌的NetworkStream.ReadAsync永远不会取消 )。 我试过关闭底层流,这导致等待ReadAsync调用抛出ObjectDisposedException,底层蓝牙连接也被关闭。 理想情况下,我不想完全切断与设备的连接只是为了停止阅读。 它似乎不是一种干净的方式,并且感觉不必拆除整个流只是为了中断va ReadAsync()调用。 任何建议?

unit testing异步操作

我想unit testing我执行的方法和异步操作: Task.Factory.StartNew(() => { // method to test and return value var result = LongRunningOperation(); }); 我在unit testing中编写必要的方法等(用c#编写),但问题是在断言测试之前异步操作没有完成。 我怎么能绕过这个? 我应该创建TaskFactory的模拟或任何其他unit testing异步操作的技巧吗?

Haskell相当于C#5 async / await

我刚刚阅读了使用await和async关键字在C#5.0中处理异步函数的新方法。 从等待的C#参考考试: private async Task SumPageSizesAsync() { // To use the HttpClient type in desktop apps, you must include a using directive and add a // reference for the System.Net.Http namespace. HttpClient client = new HttpClient(); // . . . Task getContentsTask = client.GetByteArrayAsync(url); byte[] urlContents = await getContentsTask; // Equivalently, now that you see […]