Встраивание Python в многопоточные приложения C#

Мое приложение предоставляет систему плагинов python. Чтобы вызвать python из С#. Я написал C-оболочку для встраивания dll python. Вы можете найти суть здесь суть оболочки C.

Затем я использую P/Invoke в C# для вызова C dll. Нравится:

[DllImport("PyWinAlfred.dll")]
private extern static IntPtr ExecPython(string directory, string file, string query);

Все в порядке, если я не выполнял приведенные выше коды в нескольких потоках, созданных C #. Проблема в том, что если я не использовал поток, основной поток в С# будет заблокирован, в то время как выполнение кода Python занимает много времени.
Вот код нескольких потоков С#, который я использую:

ThreadPool.QueueUserWorkItem(state =>
{
   ExecPython(directory,file,query);
});

Итак, я попытался добавить поддержку нескольких потоков в код оболочки C. Как вы можете видеть в этой сути. Я попытался добавить:

// Create GIL/enable threads
PyEval_InitThreads();
PyGILState_STATE gstate = PyGILState_Ensure();

//python codes

PyGILState_Release(gstate);

Но это не работает для меня. Когда я создам несколько потоков для вызова этой dll, я получу исключение.

Я также пробовал следующие коды. Все еще не работает.

PyThreadState* state = PyThreadState_Get();
// Once in each thread
PyThreadState* stateForNewThread = PyThreadState_New(state->interp);
PyEval_RestoreThread(stateForNewThread);

//python codes

PyEval_SaveThread();

Мне было интересно, не потому ли это, что я добавляю Py_Initialize(); в каждый вызов. Когда поток2 выполнится, Py_Initialize(); очистит всю информацию, которая может потребоваться потоку1. Я пытался вызвать Py_Initialize() при запуске моего приложения, поэтому оно будет вызываться только один раз. Но не сработало. Похоже, эти два вызова полностью изолированы в вызовах p/invoke.

Я плохо разбираюсь в C и встраиваю python, есть ли у кого-нибудь соответствующий опыт? Мой проект размещен в https://github.com/qianlifeng/WinAlfred. Если вы, ребята, хотите увидеть коды я описал выше.


person scott    schedule 25.12.2013    source источник
comment
Возможно, это не совсем то, что вам нужно, но встроить IronPython в приложение .NET намного проще, чем CPython. Недостатком является то, что некоторые библиотеки Python плохо работают с IronPython.   -  person Dirk    schedule 25.12.2013
comment
Я пробовал Ironpython, как вы сказали, некоторые библиотеки не будут работать с ним. например Запросы. Вот почему я сейчас пробую CPython.   -  person scott    schedule 26.12.2013


Ответы (1)


Наконец, я нахожу http://pythonnet.github.io/. Подробности можно найти в этом проекте WinAlfred. Я решил проблемы многопоточности в этом проекте.

person scott    schedule 25.01.2014
comment
можете ли вы указать код wox, где многопоточность используется с pythonnet? - person denfromufa; 08.02.2016