/// <summary> /// Starts the server. /// </summary> /// <param name="srcDeviceId">The source device identifier.</param> /// <param name="communicationService">The communication service.</param> private void StartServer(string srcDeviceId, IServer <Command, FetchRequest, GrpcResponse> communicationService) { // Grpc server CommunicationServer server = new CommunicationServer(communicationService, srcDeviceId); // Grpc server actions server.OnAction = async(cmd, streamId, token, header) => { return(await ActionWorker.ProcessCommand(srcDeviceId, cmd, streamId, token, header)); }; server.OnFetch = async(request, streamId, token, header) => { return(await FetchWorker.ProcessFetch(request, streamId, token, header)); }; server.OnStreamOpened = async(stream, token, header) => { return(await ActionWorker.StreamConnected(stream, token, header)); }; server.OnStreaming = async(cmd, stream, token, header) => { return(await ActionWorker.ProcessCommand(srcDeviceId, cmd, stream.Id, token, header)); }; server.OnClientDisconnected = async(id) => { await CommonSubscriptionHandler.UnregisterStream(id); }; server.OnLog += (sender, srcid, msg, level) => { CommonBaseHandler.Log(sender.ToString(), msg, level); }; server.Start(); }
private void DoFetch(object parameter) { IEnumerable<MovieEntry> entries = (IEnumerable<MovieEntry>)parameter; List<MovieEntry> processedEntries = new List<MovieEntry>(); FetchWorker[] workers = new FetchWorker[m_concurrentFetches]; WaitHandle[] doneWorkers = new WaitHandle[workers.Length]; for (int i = 0; i < workers.Length; i++) { workers[i] = new FetchWorker(m_library, processedEntries); doneWorkers[i] = workers[i].DoneSignal; } foreach (MovieEntry entry in entries) { // Wait for a thread to become available. int index = WaitHandle.WaitAny(doneWorkers); // Notify caller of progress. int percentage = (int)(((double)processedEntries.Count() / (double)entries.Count()) * 100.0); ProgressChangedEventArgs progressArgs = new ProgressChangedEventArgs(percentage, null); m_caller.Invoke(new ProgressUpdate(m_caller.backgroundFetcher_ProgressChanged), new object[] { this, progressArgs }); if (m_cancelRequested) { break; } // Start a new fetch operation. workers[index].FetchAsync(entry); } // Wait for workers to finish. At a fixed interval, poll to see if any more // workers have finished their tasks so that progress may be updated. int previousProgress = -1; while (true) { if (WaitHandle.WaitAll(doneWorkers, 500)) { break; } else { // Notify caller of progress if changed. int percentage = (int)(((double)processedEntries.Count() / (double)entries.Count()) * 100.0); if (percentage != previousProgress) { ProgressChangedEventArgs progressArgs = new ProgressChangedEventArgs(percentage, null); m_caller.Invoke(new ProgressUpdate(m_caller.backgroundFetcher_ProgressChanged), new object[] { this, progressArgs }); } previousProgress = percentage; } } // Notify caller of completion. Don't set 'cancelled' even if the process was cancelled, because this // will cause the results to be inaccessible. Even when cancelled there still might be partial results. RunWorkerCompletedEventArgs completedArgs = new RunWorkerCompletedEventArgs(processedEntries, null, false); m_caller.Invoke(new Completed(m_caller.backgroundFetcher_RunWorkerCompleted), new object[] { this, completedArgs }); }