Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调试Invoke()调用会导致调试器停止工作_C++_Multithreading_Winforms_Visual Studio 2017_Invoke - Fatal编程技术网

C++ 调试Invoke()调用会导致调试器停止工作

C++ 调试Invoke()调用会导致调试器停止工作,c++,multithreading,winforms,visual-studio-2017,invoke,C++,Multithreading,Winforms,Visual Studio 2017,Invoke,我有一个WinForm的方法,该方法由创建WinForm的线程以外的线程调用。调试时,我到达一行调用this->Invoke()和调试器似乎跳过该行并继续正常执行。但是,正常执行会有程序循环,并不断地到达Invoke调用,但不会返回到它 我在Visual Studio 2013和2017中经历过这种情况 //GUI.h delegate void Whatever(System::String ^ text); void SetConsoleTextBoxText(System::String

我有一个WinForm的方法,该方法由创建WinForm的线程以外的线程调用。调试时,我到达一行调用
this->Invoke()和调试器似乎跳过该行并继续正常执行。但是,正常执行会有程序循环,并不断地到达
Invoke
调用,但不会返回到它

我在Visual Studio 2013和2017中经历过这种情况

//GUI.h
delegate void Whatever(System::String ^ text);

void SetConsoleTextBoxText(System::String^ input)
{
    if (this->consoleTextBox->InvokeRequired)
    {
        Whatever^ we = gcnew Whatever(this, &GUI::SetConsoleTextBoxText);
        this->Invoke(we, gcnew array<Object^> { input }); //debugger hits this and breaks
    }
    else
    {
        this->consoleTextBox->Text = input;
        this->consoleTextBox->Refresh();
    }
}

ref struct Globals {
    static GUI ^ gui; //this is my "Global WinForm"
};

一段时间以来,我一直在努力解决更新
ConsoleTextBox
时出现的问题,并且在调试该问题时遇到了困难

我的语法错了吗

我的调试是否设置为忽略第一个错误

为什么调试器会执行/跳过一行,然后继续运行程序而不会再次遇到错误


提前感谢。

我仍然不知道为什么调试器在调用
调用时“中断”

但是,我已经修复了导致
调用
出现问题的线程问题,因此我不再面临这个问题

我在我的
GUI.h
文件中创建了
线程,单击开始
按钮
,而不是稍后在程序中,在
GUI.cpp
文件中创建线程

为了更加具体,我的
按钮
方法(在
GUI.h
中)调用在
GUI.h
中声明并在
GUI.cpp
中定义的方法。我最初是在GUI.cpp函数中创建线程的。现在,我在
按钮中创建线程,单击
GUI.h
中的
方法,让该线程调用
GUI.cpp
中的方法。
GUI.cpp
中的方法将方法调用到
SetTextBoxText
。如果所属线程以外的线程正在调用该方法,则该方法现在可以
调用
本身(在我的例子中,总是这样)


这是我的解决办法。如果有人能解释为什么这会使线程更安全,我很想知道。

是否有可能控件(或窗体)的窗口句柄尚未创建?选中IsHandleCreated,因为如果不是,则不应尝试设置文本,因为这可能会导致在错误的线程上创建句柄。嘿@Ben,文本框肯定已经创建,但只是为了检查,我包含了语句
if(this->consoleTextBox->IsHandleCreated)
并且它确实返回
true
。我建议您将工作转移到一个单独的函数
SetConsoleTextBoxTextImpl
,即
Whatever^we=gcnewwhatever(this,&GUI::SetConsoleTextBoxTextImpl)这样您就不会执行两次检查了,这就是重点。我可以从任何线程调用
SetConsoleTextBoxText
,它将检查是否需要通过最初创建控件的线程调用
Invoke
。对自身的调用只会使它可以从任何线程调用。然而,为了确保这不是问题所在,我继续尝试了一下。当调试器到达
Invoke()
行时,也会发生同样的情况,调试器似乎会进入该行,然后忽略/继续,并且永远不会再次到达该语句,尽管它确实应该这样做。对被调用方法的实际调用将在GUI线程上,而不是当前线程上,因此不会进入该线程。尝试在GUI更新的区域内设置一个断点,您应该能够捕获其他线程的处理。
//Different .cpp file
//Running on a different thread than the WinForm "GUI" was made on

MethodThatIsCalledALotInALoop()
{
    System::String^ sysStr = "some string";

    GUI_Example_Receive::Globals::gui->SetConsoleTextBoxText(sysStr);
}