2017-01-25 1 views
0

Ich habe eine externe Referenz in meiner .NET Konsolenanwendung, die einige Übersetzungen für große Zeichenfolgen für mich tut.In C#, wie kann man wissen, wann ein externer Dienst Rückrufe durchführt?

In einer Schleife, mache ich eine Reihe von Anrufen an den Dienst. Es gibt wahrscheinlich 5000-8000 Anrufe insgesamt.

Der Dienst erfordert, dass ich eine Callback-Funktion implementiere, damit sie mir die übersetzte Zeichenfolge zurückgeben kann, wenn die Arbeit abgeschlossen ist. In einer anderen Klasse, die die translation der Schnittstelle erbt, habe ich ihre Callback-Funktion implementiert:

class MyTranslationServiceCallback : TranslationService.ITranslationServiceCallback 
{ 
    public void TranslateTextCallback(string sourceContent, string responseContent) 
    { 
     UpdateMyDatabase(responseContent); 
    } 
} 

Wenn das Debuggen, habe ich Console.Readkey am Ende meines Main() hinzugefügt, um die App zu verhindern, dass zu schließen, so dass es beenden kann alle bekommen der Rückrufe. Bisher habe ich einfach angenommen, dass wenn es für eine Minute oder so die Callback-Funktion beendet, es "vollständig" ist (ich weiß, das ist schlecht).

So wie es aussieht:

class Program 
{ 
    static void Main(string[] args) 
    { 
     foreach (var item in itemList) 
     { 
      TranslationService.TranslateText(item.EnglishText, "french"); 
     } 

     Console.Readkey() 
    } 
} 

Was ist der richtige Weg, um zu bestimmen, ob oder ob nicht alle Rückrufe abgeschlossen sind?

+0

Ist der Übersetzungsdienst des Status nicht sagen? Wenn nicht, können Sie die von Ihnen getätigten Anrufe zählen und die Rückrufe zählen. – Vijay

+0

@ Vijayakrishna Nein, das ist ein Inhouse-Service, der relativ neu ist. Der Übersetzungsdienst verfolgt nichts und gibt nur die Quellzeichenfolge und die übersetzte Zeichenfolge in ihrer Rückruffunktion zurück. – AlbatrossCafe

Antwort

0

Warum nicht das in .NET integrierte Async-Framework verwenden? Alles, was Sie tun müssen, ist Aufgaben abzufeuern und in einem Array zu verfolgen, wo Sie dann Task.WhenAll aufrufen können, um das Programm zu blockieren, bis alle Aufgaben abgeschlossen sind.

Hinweis: Ich verwende das NuGet-Paket Nito.AsyncEx, um Async-Code von Console-Apps auszuführen.

class Program 
    { 
     static int Main(string[] args) 
     { 
     return AsynContent.Run(() => MainAsync(args)); 
     } 

     static async Task<int> MainAsync(string[] args) 
     { 
     var taskList = new List<Task>(); 

     foreach (var item in itemList) 
     { 
      Task.Factory.StartNew(() => TranslationService.TranslateText(item.EnglishText, "french"); 
     } 

     Task.WhenAll(taskList.ToArray()); 
     } 
} 
1

Da der Übersetzungsdienst keine Möglichkeit hat, den Status von Übersetzungen anzugeben, müssen Sie die getätigten Anrufe und Rückrufe protokollieren. Erstellen Sie ein Singleton, das bei jedem Aufruf einen Zähler und eine Erhöhung enthält. Verringern Sie die Anzahl bei jedem Rückruf.

0

Wenn Sie dies in .NET implementieren, dann ist async/await Ihr Freund.

Es wäre toll, wenn TranslationService, anstatt das Ergebnis über Rückrufe zurückgeben, eine Task<string> zurückgegeben.

Dann könnten Sie die folgende Umsetzung:

static async Task TranslateAllItems(IEnumerable<Item> list) 
{ 
    foreach(var item in itemList) 
    { 
     string result = await TranslationService.TranslateText(item.EnglishText, "french"); 
     UpdateMyDatabase(item.EnglishText, content); 
    } 
} 

static void Main(string[] args) 
{ 
    Task task = TranslateAllItems(itemList); 
    task.Wait(); 
    Console.ReadKey(); 
} 

Die obige Lösung jede Übersetzung in Folge durchführen würde, für eine Übersetzungsaufgabe wartet mit dem nächsten abgeschlossen ist, bevor begonnen wird.

Wenn es schneller sein würde, alle Übersetzungen zu starten, dann warten, bis die gesamte Charge zu beenden:

static Task TranslateAllItems(IEnumerable<Item> list) 
{ 
    List<Task> waitingTasks = new List<Task>(); 
    foreach(var item in itemList) 
    { 
      string englishText = item.EnglishText; 
      var task = TranslationService.TranslateText(englishText , "french") 
       .ContinueWith(taskResult => UpdateMyDatabase(englishText, taskResult.Result); 
      waitingTasks.Add(task); 
    } 
    return Task.WhenAll(waitingTasks); 
} 
Verwandte Themen