我的.NET 控制台应用程序中有一个外部引用,可以为我提供大字符串的语言翻译。
在循环中,我对服务进行了一系列调用。总共可能有5000-8000个电话。
该服务要求我实现一个回调函数,以便在完成工作时它可以将已翻译的字符串返回给我。在另一个继承了TranslationService接口的类中,我实现了它们的回调函数:
class MyTranslationServiceCallback : TranslationService.ITranslationServiceCallback
{
public void TranslateTextCallback(string sourceContent, string responseContent)
{
UpdateMyDatabase(responseContent);
}
}
调试时,我在Console.Readkey
的最后添加了Main()
,以防止应用程序关闭,以便完成所有回调。到目前为止,我刚刚假设当它停止进入回调函数一分钟左右时它已经完成了#34; (我知道,这很糟糕)。
所以看起来像:
class Program
{
static void Main(string[] args)
{
foreach (var item in itemList)
{
TranslationService.TranslateText(item.EnglishText, "french");
}
Console.Readkey()
}
}
确定所有回调是否已完成的正确方法是什么?
答案 0 :(得分:1)
由于翻译服务无法告知翻译状态,因此您需要跟踪所做的调用和回调。创建一个具有计数器并在每次调用时递增的单例。减少每次回叫的计数。
答案 1 :(得分:0)
为什么不使用.NET内置的异步框架?您需要做的就是触发任务并在数组中跟踪它们,然后您可以调用Task.WhenAll
来阻止程序直到所有任务都完成。
注意:我正在使用Nito.AsyncEx NuGet包,以便从控制台应用运行异步代码。
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());
}
}
答案 2 :(得分:0)
如果您在.NET中实现此功能,那么async / await就是您的朋友。
如果不是通过回调返回结果,TranslationService
返回Task<string>
,那就太棒了。
然后你可以实现以下内容:
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();
}
上述解决方案将按顺序执行每个翻译,等待一个翻译任务完成,然后再开始下一个翻译任务。
如果启动所有翻译会更快,那么等待整个批次完成:
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);
}