Из C# нам нужно вызвать функцию Python, в данном случае функцию lemmatize библиотеки nltk (которая до сих пор не имеет хорошей реализации на C#). Мы называем это так:
Код: Выделить всё
private string Lemmatize(string word)
{
using (Py.GIL())
{
using (var scope = Py.CreateScope())
{
dynamic nltk = Py.Import("nltk");
var lemmatizer = nltk.stem.WordNetLemmatizer();
var lemma = lemmatizer.lemmatize(word);
return lemma;
}
}
}
Он отлично работает в тестовом приложении из консольного приложения .net. Когда мы применили это к реальному приложению, в котором есть асинхронные функции, мы обнаружили, что функция обычно зависает в момент использования (Py.GIL()). Все приложение работает в одном потоке, потому что асинхронные функции работают везде, но каждый из них вызывается с await. Поэтому точка вызова выглядит так:
Код: Выделить всё
private async Task LemmatizeAll(IEnumerabe words)
{
var result = new List();
foreach(var word in words)
{
var item = Lemmatize(word);
result.Add(item);
}
return result;
}
//
var lemmas = await LemmatizeAll(new [] {"running", "man"});
Я понимаю, что Py.GIL() — это по большей части семафор, не позволяющий одновременно запускать несколько потоков, но сейчас это происходит не так. Он выполняется только из одного потока, но из разных потоков из-за асинхронного ожидания. Быть повешенным из-за этого нехорошо.
Как использовать скрипты Python в такой среде? Есть совет?
Подробнее здесь:
https://stackoverflow.com/questions/787 ... pp-to-hang