Tag: 异步

如何正确使用Task.WhenAll()

我正在尝试使用Task.WhenAll等待完成多个任务。 我的代码如下 – 它应该启动多个异步任务,每个异步任务检索一个总线路由,然后将它们添加到本地arrays。 但是,Task.WhenAll(…)立即返回,并且本地路由数组的计数为零。 这看起来很奇怪,因为我希望每个任务中的各种“等待”语句意味着流程被暂停,并且任务在完成之前不会返回。 List monitoredTasks = new List(); foreach (BusRouteIdentifier bri in stop.services) { BusRouteRequest req = new BusRouteRequest(bri.id); // Start a new task to fetch the route for each stop Task getRouteTask = Task.Factory.StartNew(async () => { var route = await BusDataProviderManager.DataProvider.DataBroker.getRoute(req); // Add the route to our array (on UI […]

等待AsyncMethod()与等待等待等待Task.Factory.StartNew (AsyncMethod)

给定以下方法: public async Task DoSomethingAsync() { // do some work await OpenSomeFileAsync(); return new MyObject(); } 是否有区别: public async void SomeEventHandler(EventArgs args) { var myObject = await await Task.Factory.StartNew<Task>( DoSomethingAsync); // do something with myObject } 和: public async void SomeEventHandler(EventArgs args) { var myObject = await DoSomethingAsync(); // do something with myObject } 我认为DoSomethingAsync的“做一些工作”部分会在第一种情况下立即发生在新任务中,但说实话我并不完全理解Task,async和await是如何工作的,而且我很漂亮确定我只是为自己过度复杂的事情。 […]

C#Socket.Receive消息长度

我目前正在开发一个可以接受来自多个客户端计算机的多个连接的C#Socket服务器。 服务器的目标是允许客户端从服务器事件“订阅”和“取消订阅”。 到目前为止,我已经在这里采取了一个快乐的好看: http : //msdn.microsoft.com/en-us/library/5w7b7x5f( v = VS.100) .aspx和http://msdn.microsoft.com/ en-us / library / fx6588te.aspx的想法。 我发送的所有消息都是加密的,因此我接收了我希望发送的字符串消息,将其转换为byte []数组,然后在将消息长度预先挂起到数据之前加密数据并通过连接发送出去。 令我印象深刻的一件事是:在接收端,当收到消息的一半时,Socket.EndReceive()(或相关的回调)似乎可能会返回。 是否有一种简单的方法可以确保每条消息都“完整”并且一次只收到一条消息? 编辑:例如,我认为.NET / Windows套接字没有“包装”消息,以确保在一个Socket.Receive()调用中收到与Socket.Send()一起发送的单个消息? 或者是吗? 到目前为止我的实施: private void StartListening() { IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0], Constants.PortNumber); Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); listener.Bind(localEP); listener.Listen(10); while (true) { // Reset the event. this.listenAllDone.Reset(); […]

任务取消exception(ThrowForNonSuccess)

这是这个问题的延续: 多任务延续 我在答案中更改了我的代码,但是现在我在尝试运行任务时收到TaskCancelledExceptions 。 public virtual async Task RunAsync(TaskWithProgress task) { Show(); TaskIsRunning(); await SetCompletedHandler(TaskComplete()); await SetCancelledHandler(TaskCancelled()) await SetFaultedHandler(TaskFaulted()); await task; Close(); } 但是以下代码没有。 我有点卡住为什么。 public virtual Task RunAsync(TaskWithProgress task) { Show(); TaskIsRunning(); SetCompletedHandler(TaskComplete()); SetCancelledHandler(TaskCancelled()) SetFaultedHandler(TaskFaulted()); return task; } 调用代码基本上涉及以下内容: await progressDialog.RunAsync(task); 编辑: 我没有在任何地方取消cancellationtoken ,所以我不明白为什么这会抛出exception。 三个SetXXXHandler()方法基本上执行以下具有不同延续状态的代码: task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler); 堆栈跟踪在这里: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task […]

命名管道 – 异步偷看

当在异步模式下打开的System.IO.Pipe.NamedPipeServerStream有更多可用于读取的数据时,我需要找到一种通知方式 – WaitHandle将是理想的。 我不能简单地使用BeginRead()来获取这样的句柄,因为我可能会被另一个想要写入管道的线程发出信号 – 所以我必须释放管道上的锁并等待写入完成,和NamedPipeServerStream没有CancelAsync方法。 我也尝试调用BeginRead(),然后如果线程被发出信号,则在管道上调用win32函数CancelIO,但我不认为这是一个理想的解决方案,因为如果在数据到达和处理时调用CancelIO,它将会被删除 – 我仍然希望保留这些数据,但是在写入之后稍后处理它。 我怀疑win32函数PeekNamedPipe可能有用,但我想避免不得不用它连续轮询新数据。 在上面的文字有点不清楚的情况下,这里大致是我想要做的… NamedPipeServerStream pipe; ManualResetEvent WriteFlag; //initialise pipe lock (pipe) { //I wish this method existed WaitHandle NewDataHandle = pipe.GetDataAvailableWaithandle(); Waithandle[] BreakConditions = new Waithandle[2]; BreakConditions[0] = NewDataHandle; BreakConditions[1] = WriteFlag; int breakcode = WaitHandle.WaitAny(BreakConditions); switch (breakcode) { case 0: //do a read on the pipe […]

将逻辑调用上下文从OWIN管道传递到WebApi控制器

我正在尝试根据Stephen Cleary的post传递关于逻辑调用上下文的上下文信息(使用CallContext.LogicalSetData(CallContextKey, value) ) http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal .html ; 并受到https://github.com/neuecc/OwinRequestScopeContext中代码的启发。 该值将在OWIN管道中可用,但在呼叫进入WebApi控制器时不可用,该值未设置。 我还注意到在控制器中设置断点时,我看不到调用堆栈中的OWIN管道。 显然,ASP.NET正在单独的调用上下文中进行控制器调用。 所以, 为什么(以及如何)ASP.NET将调用上下文从OWIN管道隔离到WebApi控制器? 如何将上下文数据从Pipeline传递到控制器?

如果任务等待某事,任务状态将更改为RanToCompletion

这个问题描述了同样的问题 – MSDN Developer Forum 。 这个问题没有得到公认的答案,所给出的任何答案都不能适用于我的案例(因此是一个不同的问题)。 问题也来自我之前提出的问题 ,但是,由于性质和具体问题的不同,我问了一个新问题。 完整代码可以在这里找到: http : //pastebin.com/uhBGWC5e *唯一改变的是任务完成检查( while – > Task.WhenAll )。 等待任务内部的异步操作时,即使任务仍在运行,任务状态也会更改为RanToCompletion 。 现在,让我们看看设置: // Start async. Task t1 = Task.Factory.StartNew(Accept, s1); Task t2 = Task.Factory.StartNew(Accept, s1); Task.WhenAll(t1, t2).Wait(); Accept方法: public static async void Accept(object state) { TcpListenerEx server = (TcpListenerEx) state; IPEndPoint endPoint = server.LocalEndpoint as […]

如何在C#中等待单个事件,超时和取消

所以我的要求是让我的函数等待第一个实例,来自另一个类和另一个线程的event Action ,并在我的线程上处理它,允许等待被超时或CancellationToken中断。 我想创建一个我可以重用的generics函数。 我设法创造了一些(我认为)我需要的选项,但两者看起来都比我想象的要复杂得多。 用法 为了清楚serialDevice ,此函数的示例使用将如下所示,其中serialDevice在单独的线程上吐出事件: var eventOccurred = Helper.WaitForSingleEvent( cancellationToken, statusPacket => OnStatusPacketReceived(statusPacket), a => serialDevice.StatusPacketReceived += a, a => serialDevice.StatusPacketReceived -= a, 5000, () => serialDevice.RequestStatusPacket()); 选项1-ManualResetEventSlim 这个选项并不错,但是对于ManualResetEventSlim的Dispose处理比看起来应该更糟糕。 它给了ReSharper适合我在闭包内访问修改/处理的东西,而且真的很难遵循,所以我甚至不确定它是否正确。 也许有一些我遗漏的东西可以清理它,这是我的偏好,但我不会随便看到它。 这是代码。 public static bool WaitForSingleEvent(this CancellationToken token, Action handler, Action<Action> subscribe, Action<Action> unsubscribe, int msTimeout, Action initializer = null) { var […]

C#AsyncCallback是否创建了一个新线程?

我编写了一个侦听其中一个端口的HttpListener : httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpListener); ListenerCallback处理在侦听器uri上接收的任何请求。 如果在处理请求期间发生exception,它将运行一个诊断例程,该例程尝试命中侦听器uri以检查侦听器是否实际处于活动状态并侦听uri并写入侦听器返回的响应日志。 Listener只是将字符串Listening…返回给这样的虚拟请求。 现在在测试期间,当导致执行诊断模块的其他模块发生exception时,我可以看到监听器在检查日志时正确地返回了Listening… 但是,当ListenerCallback发生exception时,尝试命中诊断内的侦听器URI会引发以下exception: System.Net.WebException : The operation has timed out at System.Net.HttpWebRequest.GetResponse() at MyPackage.Diagnostics.hitListenerUrl(String url) in c:\SW\MyApp\MyProj\Diagnostics.cs:line 190 诊断模块中的第190行如下: 189 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 190 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 现在,如果AsyncCallback调度新线程并在该新线程中运行ListenerCallback ,则在通过诊断发送虚拟请求时,它不得导致Operation Timeout 。 这就是我认为理想的行为,因为它是*Async*Callback 。 事实上MSDN也说同样的话 : 使用AsyncCallback委托在单独的线程中处理异步操作的结果。 但似乎并非如此。 我在这里错过了什么吗? 视觉解读:

拨打许多网络服务的最佳方式?

我有30家子公司,每家公司都实施了他们的网络服务(使用不同的技术)。 我需要实现一个Web服务来聚合它们,例如,所有子公司Web服务都有一个名为GetUserPoint(int nationalCode)的Web方法,我需要实现我的Web服务,它将调用所有这些并收集所有的回复(例如积分总和)。 这是我的基类: public abstract class BaseClass { // all same attributes and methods public long GetPoint(int nationalCode); } 对于每个子公司Web服务,我实现了一个inheritance此基类并定义自己的GetPoint方法的类。 public class Company1 { //implement own GetPoint method (call a web service). } 至 public class CompanyN { //implement own GetPoint method (call a web service). } 所以,这是我的网络方法: [WebMethod] public long MyCollector(string nationalCode) { […]