/// <summary> /// Sends the command back. /// </summary> /// <param name="data">Data.</param> public virtual void SendBack(CommandData data) { data.Recipient = this.SenderId; CoreInstance.SendCommand(data); AfterSend?.Invoke(this); }
/// <summary> /// 将Http请求作为异步请求发送 /// </summary> /// <param name="request">要发送的HTTP请求消息。</param> /// <param name="cancellationToken">取消操作的取消令牌。</param> /// <returns>表示异步操作的任务对象。</returns> protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { try { BeforeSend?.Invoke(this, EventArgs.Empty); return(await(SendAsyncMethod.Invoke(Handler, new object[] { request, cancellationToken }) as Task <HttpResponseMessage>)); // 调用父类的SendAsync方法 } finally { AfterSend?.Invoke(this, EventArgs.Empty); } }
private async Task FlushAsync(bool isCalledFromTimer) { if (isCalledFromTimer && ShutdownCalled) // don't perform timer actions if we're shutting down { return; } if (_endpoints.Length == 0) { Debug.WriteLine("StackExchange.Metrics: No endpoints. Dropping data."); return; } foreach (var endpoint in _endpoints) { Debug.WriteLine($"StackExchange.Metrics: Flushing metrics for {endpoint.Name}"); try { await endpoint.Handler.FlushAsync( RetryInterval, _maxRetries, // Use Task.Run here to invoke the event listeners asynchronously. // We're inside a lock, so calling the listeners synchronously would put us at risk of a deadlock. info => Task.Run( () => { info.Endpoint = endpoint.Name; try { AfterSend?.Invoke(info); } catch (Exception ex) { SendExceptionToHandler(ex); } } ), ex => SendExceptionToHandler(ex) ); } catch (Exception ex) { // this will be hit if a sending operation repeatedly fails SendExceptionToHandler(ex); } } }
private void DoSocketSend(IAsyncResult ar) { SocketError socketError; int length; try { //получаем количество отправленных данных length = _socket.EndSend(ar, out socketError); } catch (Exception e) { DoDisconnect(e); return; } finally { //вызываем событие, сигнализирующее об отправки очередной порции данных AfterSend?.Invoke(this, new SocketSendEventArgs(this, (byte[])ar.AsyncState, _offset)); } //проверяем на ошибки отправки данных if (socketError != SocketError.Success || length <= 0) { DoDisconnect(new Exception(socketError.ToString())); return; } lock (_socket) { //если очередь пуста, то выставляем флаг о том, что ожидающих данных нет _isSendComplete = _sendQueue.Count == 0; if (!_isSendComplete) { //получаем первую порцию данных var data = _sendQueue.Dequeue(); try { //отправляем порцию данных _socket.BeginSend(data.Item1, 0, data.Item2, SocketFlags.None, DoSocketSend, data.Item1); } catch (Exception e) { DoDisconnect(e); } } } }
public async Task <ScrobbleResponse> ScrobbleAsyncInternal(IEnumerable <Scrobble> scrobbles) { var scrobblesList = scrobbles.ToList(); var cached = await GetCachedAsync(); var pending = scrobblesList.Concat(cached).OrderBy(s => s.TimePlayed).ToList(); if (!pending.Any()) { return(new ScrobbleResponse(LastResponseStatus.Successful)); } var batches = pending.Batch(MaxBatchSize); var responses = new List <ScrobbleResponse>(pending.Count % MaxBatchSize); var responseExceptions = new List <Exception>(); foreach (var batch in batches) { var command = new ScrobbleCommand(_auth, batch) { HttpClient = HttpClient }; try { var response = await command.ExecuteAsync(); responses.Add(response); } catch (HttpRequestException httpEx) { responseExceptions.Add(httpEx); } } ScrobbleResponse scrobblerResponse; if (!responses.Any() || responses.All(r => r.Success)) { scrobblerResponse = new ScrobbleResponse(LastResponseStatus.Successful); } else { try { var firstBadResponse = responses.FirstOrDefault(r => !r.Success && r.Status != LastResponseStatus.Unknown); var originalResponseStatus = firstBadResponse != null ? firstBadResponse.Status : LastResponseStatus.RequestFailed; // TODO check httpEx var cacheStatus = await CacheAsync(scrobblesList, originalResponseStatus); scrobblerResponse = new ScrobbleResponse(cacheStatus); } catch (Exception e) { scrobblerResponse = new ScrobbleResponse(LastResponseStatus.CacheFailed) { Exception = e }; } } var ignoredScrobbles = responses.SelectMany(r => r.Ignored); scrobblerResponse.Ignored = ignoredScrobbles; AfterSend?.Invoke(this, scrobblerResponse); return(scrobblerResponse); }
public async Task <ScrobbleResponse> ScrobbleAsyncInternal(IEnumerable <Scrobble> scrobbles) { var scrobblesList = new ReadOnlyCollection <Scrobble>(scrobbles.ToList()); var cached = await GetCachedAsync(); var pending = scrobblesList.Concat(cached).OrderBy(s => s.TimePlayed).ToList(); if (!pending.Any()) { return(new ScrobbleResponse(LastResponseStatus.Successful)); } var batches = pending.Batch(MaxBatchSize); var responses = new List <ScrobbleResponse>(pending.Count % MaxBatchSize); var responseExceptions = new List <Exception>(); foreach (var batch in batches) { var command = new ScrobbleCommand(Auth, batch) { HttpClient = HttpClient }; try { var response = await command.ExecuteAsync(); var acceptedMap = new HashSet <Scrobble>(pending); foreach (var ignored in response.Ignored) { acceptedMap.Remove(ignored); } await RemoveFromCacheAsync(acceptedMap); responses.Add(response); } catch (HttpRequestException httpEx) { responseExceptions.Add(httpEx); } } ScrobbleResponse scrobblerResponse; if (!responses.Any() || responses.All(r => r.Success)) { scrobblerResponse = new ScrobbleResponse(LastResponseStatus.Successful); } else { var firstBadResponse = responses.FirstOrDefault(r => !r.Success && r.Status != LastResponseStatus.Unknown); var originalResponseStatus = firstBadResponse?.Status ?? LastResponseStatus.RequestFailed; // TODO check httpEx var cacheStatus = await CacheAsync(scrobblesList, originalResponseStatus); scrobblerResponse = new ScrobbleResponse(cacheStatus); } scrobblerResponse.Ignored = responses.SelectMany(r => r.Ignored); scrobblerResponse.AcceptedCount = responses.Sum(r => r.AcceptedCount); AfterSend?.Invoke(this, scrobblerResponse); return(scrobblerResponse); }