Можно ли выполнить C# обратных вызовов к неуправляемой функции в потоке? - PullRequest
0 голосов
/ 13 апреля 2020

Это дополнительный вопрос о этом . В основном я пытаюсь отправить обратный вызов C# в модуль Python с помощью оболочки C ++. проблема заключается в том, что основной метод - это метод блокировки (некоторое время l oop, который продолжает отправлять информацию обратным вызовам. Проблема в том, что он настолько быстр, что C# GUI не может справиться с этим и таким образом, перестает отвечать на запросы.

Я пытался использовать событие timer Tick() для отображения информации каждую секунду, но кажется, что обратный вызов настолько истощает процесс, что сам таймер не может выводиться. Я даже пытался использовать поток для выполнения обратного вызова, но это также не дает результатов, то есть приложение по-прежнему не отвечает.

Мой вопрос: есть ли что-то, что я могу сделать, чтобы исправить это со стороны C#? Например, может мы заставляем обратный вызов каким-то образом запускаться в отдельном потоке, который не делает приложение не отвечающим на запросы?

Обновление

Вот еще немного информации (взято из связанного вопроса):

Мой DllImport выглядит следующим образом:

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Initialize(bool showFeed);

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Start(bool async);

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Stop();

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetCpuAffinity(int mask);



public delegate void CallbackDelegate(bool status, string message);
[MethodImplAttribute(MethodImplOptions.InternalCall)]

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void AddCallback(IntPtr fn);

[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void RemoveCallback(IntPtr fn);

И это мой C# обратный вызов:

private CallbackDelegate del;
public void SetUpCallback()
{
    txtLog.Text += "Registering C# callback...\r\n";
    del = new CallbackDelegate(callback01);
    AddCallback(Marshal.GetFunctionPointerForDelegate(del));
    txtLog.Text += "Calling passed C++ callback...\r\n";
}

bool status;
string id;
public void callback01(bool status, string id)
{
     this.status = status;
     this.id = id;
}

В основном, когда вы звоните Start() основной l * 1 033 * начинается, и обратный вызов вызывается косвенно.

Если я попытаюсь запустить Пуск с использованием потока, я больше не получу обратного вызова:


Thread t;
private void btnRunService_Click(object sender, EventArgs e)
{
    tmrFetchStatus.Start();
    //Start(chkboxAsync.Checked);
    t = new Thread(new ThreadStart(() =>
    {
         RunService();
    }));
    t.IsBackground = true;
    t.Start();
}

void RunService()
{
    Start(chkboxAsync.Checked);

    if (txtLog.InvokeRequired)
    {
        txtLog.Invoke(new MethodInvoker(()=>
        {
            txtLog.Text += "OK";  
        }));
    }
    else
    {
        txtLog.Text += "OK"; 
    }
}

1 Ответ

1 голос
/ 13 апреля 2020

Как уже отмечалось, проблема с потоками была вызвана тем, что метод Start не вызывался в том же потоке, что и метод AddCallback.

При работе с зависимыми вызовами взаимодействия (или фактически зависимыми вызовами в Вообще) лучше остаться в одной теме, если вы не знаете, что это не имеет значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...