Tag: 异步

等待基于任务的队列

我想知道是否存在ConcurrentQueue的实现/包装器,类似于BlockingCollection ,其中从集合中获取不会阻塞,而是异步并且将导致异步等待直到将项放入队列中。 我已经提出了自己的实现,但它似乎没有按预期执行。 我想知道我是否正在重塑已经存在的东西。 这是我的实现: public class MessageQueue { ConcurrentQueue queue = new ConcurrentQueue(); ConcurrentQueue<TaskCompletionSource> waitingQueue = new ConcurrentQueue<TaskCompletionSource>(); object queueSyncLock = new object(); public void Enqueue(T item) { queue.Enqueue(item); ProcessQueues(); } public async Task Dequeue() { TaskCompletionSource tcs = new TaskCompletionSource(); waitingQueue.Enqueue(tcs); ProcessQueues(); return tcs.Task.IsCompleted ? tcs.Task.Result : await tcs.Task; } private void ProcessQueues() […]

异步迭代器任务<IEnumerable >

我正在尝试实现一个返回迭代器的异步函数。 这个想法如下: private async Task<IEnumerable> TestAsync(string testString) { foreach (char c in testString.ToCharArray()) { // do other work yield return c; } } 但是,有一个错误消息,该函数不能是迭代器块,因为Task<IEnumerable>不是迭代器接口类型。 有解决方案吗?

获取异步HttpWebRequest的响应

我想知道是否有一个简单的方法来获得异步httpwebrequest的响应。 我已经在这里看到了这个问题但是我想要做的就是将字符串forms的响应(通常是json或xml)返回到另一个方法,然后我可以解析它/相应地处理它。 下面是一些代码: 我在这里有这两个静态方法,我认为这些方法是线程安全的,因为所有的参数都被传入并且方法没有共享的局部变量? public static void MakeAsyncRequest(string url, string contentType) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = contentType; request.Method = WebRequestMethods.Http.Get; request.Timeout = 20000; request.Proxy = null; request.BeginGetResponse(new AsyncCallback(ReadCallback), request); } private static void ReadCallback(IAsyncResult asyncResult) { HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; try { using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult)) { Stream responseStream = response.GetResponseStream(); using […]

C#Begin / EndReceive – 如何读取大数据?

当以1024块的数据块读取数据时,如何继续从接收大于1024字节的消息的套接字读取,直到没有数据为止? 我应该只使用BeginReceive来读取数据包的长度前缀,然后一旦检索到它,使用Receive()(在异步线程中)读取数据包的其余部分? 或者还有另一种方式吗? 编辑: 我认为Jon Skeet的链接有解决方案,但是有一些关于该代码的speedbump。 我使用的代码是: public class StateObject { public Socket workSocket = null; public const int BUFFER_SIZE = 1024; public byte[] buffer = new byte[BUFFER_SIZE]; public StringBuilder sb = new StringBuilder(); } public static void Read_Callback(IAsyncResult ar) { StateObject so = (StateObject) ar.AsyncState; Socket s = so.workSocket; int read = s.EndReceive(ar); if […]

为什么异步委托方法需要调用EndInvoke?

为什么委托需要在方法触发之前调用EndInvoke? 如果我需要调用EndInvoke(它阻塞线程)那么它真的不是异步调用吗? 这是我试图运行的代码。 class Program { private delegate void GenerateXmlDelegate(); static void Main(string[] args) { GenerateXmlDelegate worker = new GenerateXmlDelegate(GenerateMainXml); IAsyncResult result = worker.BeginInvoke(null, null); } private static void GenerateMainXml() { Thread.Sleep(10000); Console.WriteLine(“GenerateMainXml Called by delegate”); } }

如果它没有抛出,则从工厂方法缓存结果

更新:@usr指出我错误地认为Lazy的默认线程安全模式是LazyThreadSafetyMode.PublicationOnly …后严重修改… 我想懒惰地通过async工厂方法计算一个值(即它返回Task )并在成功时缓存它。 在例外情况下,我想让我可以使用它。 但是,我不想成为Lazy在其默认模式下具有的exception缓存行为 ( LazyThreadSafetyMode.ExecutionAndPublication ) exception缓存:使用工厂方法时,会缓存exception。 也就是说,如果工厂方法在线程第一次尝试访问Lazy对象的Value属性时抛出exception,则每次后续尝试都会抛出相同的exception。 这确保了对Value属性的每次调用都会产生相同的结果,并避免在不同的线程获得不同结果时可能出现的细微错误。 懒惰代表一个实际的T,否则它将在某个早期点(通常在启动期间)初始化。 在那个早期点失败通常是致命的。 如果存在可恢复故障的可能性,我们建议您将重试逻辑构建到初始化例程(在本例中为工厂方法),就像您没有使用延迟初始化一样。 Stephen Toub有一个AsyncLazy类和AsyncLazy似乎恰到好处: public class AsyncLazy : Lazy<Task> { public AsyncLazy(Func<Task> taskFactory) : base(() => Task.Factory.StartNew(() => taskFactory()).Unwrap()) { } public TaskAwaiter GetAwaiter() { return Value.GetAwaiter(); } } 然而,这与默认的Lazy实际上是相同的行为 – 如果出现问题,则不会重试。 我正在寻找与Lazy(Func, LazyThreadSafetyMode.PublicationOnly)兼容的Task ,即它应该按照指定的方式运行: – 锁定的替代方法在某些情况下,您可能希望避免Lazy对象的默认锁定行为的开销。 在极少数情况下,可能存在死锁的可能性。 在这种情况下,您可以使用Lazy(LazyThreadSafetyMode)或Lazy(Func,LazyThreadSafetyMode)构造函数,并指定LazyThreadSafetyMode.PublicationOnly。 如果线程同时调用Value属性,这使Lazy对象能够在多个线程中的每个线程上创建一个延迟初始化对象的副本。 Lazy对象确保所有线程使用延迟初始化对象的相同实例并丢弃未使用的实例。 因此,降低锁定开销的成本是您的程序有时可能会创建并丢弃昂贵对象的额外副本。 […]

将async / await转换为Task.ContinueWith

这个问题是由对这个问题的评论引发的: 如何在没有Microsoft.Bcl.Async情况下将非线性async/await代码反向移植到.NET 4.0? 在链接的问题中,我们有一个WebRequest操作,如果它一直失败,我们想要重试有限次数。 Async/await代码可能如下所示: async Task GetResponseWithRetryAsync(string url, int retries) { if (retries < 0) throw new ArgumentOutOfRangeException(); var request = WebRequest.Create(url); while (true) { WebResponse task = null; try { task = request.GetResponseAsync(); return (HttpWebResponse)await task; } catch (Exception ex) { if (task.IsCanceled) throw; if (–retries == 0) throw; // rethrow last error […]

使用进度条下载异步文件

随着WebClient下载进度的变化,我试图让进度条的进度发生变化。 这个代码仍然下载文件,当我调用startDownload() ,窗口会在下载文件时冻结。 我希望用户能够在启动屏幕加载时看到进度更改。 有没有办法解决这个问题,以便用户可以看到progressBar2的progressBar2发生变化? private void startDownload() { WebClient client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); client.DownloadFileAsync(new Uri(“http://joshua-ferrara.com/luahelper/lua.syn”), @”C:\LUAHelper\Syntax Files\lua.syn”); } void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { double bytesIn = double.Parse(e.BytesReceived.ToString()); double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); double percentage = bytesIn / totalBytes * 100; label2.Text = “Downloaded ” + e.BytesReceived […]

如何使用call / cc实现c#5.0中的新异步function?

我一直在关注有关c#5.0中新的asyncfunction的新公告。 我对继续传递样式以及新的c#编译器对Eric Lippert的post中的代码片段所做的转换有基本的了解: async void ArchiveDocuments(List urls) { Task archive = null; for(int i = 0; i < urls.Count; ++i) { var document = await FetchAsync(urls[i]); if (archive != null) await archive; archive = ArchiveAsync(document); } } 我知道有些语言通过call-with-current-continuation( callcc )本地实现continuation,但我真的不明白它是如何工作的或者它究竟是做什么的。 所以这就是问题:如果安德斯等人。 我决定咬紧牙关,只是在c#5.0中实现callcc而不是async / await特殊情况,上面的代码片段会是什么样子?

如何异步调用wcf服务

如果wcf服务设计如下,那么请指导我如何从客户端Asynchronously调用Add()函数。 谢谢 [ServiceContract] public interface IAddTwoNumbers { // If the asynchronous method pair // appears on the client channel, the client can call // them asynchronously to prevent blocking. [OperationContract (AsyncPattern=true)] IAsyncResult BeginAdd(int a, int b, AsyncCallback cb, AsyncState s); [OperationContract] int EndAdd(IAsyncResult r); // This is a synchronous version of the BeginAdd/EndAdd pair. // […]