简体   繁体   English

时间问题? 程序可以在Visual Studio中正常运行,但不能独立运行

[英]Timing issue? Program runs fine in Visual Studio but not standalone

I have a native C++ DLL. 我有一个本地C ++ DLL。 The DLL creates a thread which repeatedly reads data from an external device. DLL创建一个线程,该线程反复从外部设备读取数据。 If data is not read quickly enough, the device can overflow. 如果读取数据的速度不够快,则设备可能会溢出。

The 'read' loop looks something like this: “读取”循环看起来像这样:

while (true)
{
    read_from_device();

    buffer_data();

    Sleep(5);  //Allow data to accumulate 
}

I also have a C# application which utilises the above DLL. 我也有一个利用以上DLL的C#应用​​程序。 It calls a function in the DLL to kick off the 'read' thread, and then periodically calls another function in the DLL to check whether all the data has been read from the external device. 它调用DLL中的一个函数以启动“读取”线程,然后定期调用DLL中的另一个函数以检查是否已从外部设备读取了所有数据。

Both the application and the DLL are built in 'Debug' mode in Visual Studio (2008 in this case). 应用程序和DLL都在Visual Studio(本例中为2008)的“调试”模式下构建。

If I run the application through Visual Studio everything is fine: data is read from the external device and no overflows occur. 如果我通过Visual Studio运行该应用程序,则一切都很好:从外部设备读取数据,并且不会发生溢出。

When I run the same application 'standalone' (by directly running the .exe), I encounter overflows. 当我运行相同的应用程序“独立”(通过直接运行.exe)时,遇到溢出。

I think the only difference is that in the first instance the Visual Studio debugger is automatically attached to the application? 我认为唯一的区别是,在第一个实例中,Visual Studio调试器会自动附加到应用程序吗? Bear in mind I have no breakpoints set. 请记住,我没有设置断点。

There must be a timing issue present in my application which is somehow rectified when the debugger is attached to it? 我的应用程序中一定存在一个定时问题,将调试器附加到它后,该问题可以通过某种方式解决吗?

How on earth can I go about debugging this problem? 我到底该如何调试这个问题?

What other differences are there between running an application via Visual Studio and running it directly? 通过Visual Studio运行应用程序和直接运行它之间还有什么其他区别?

EDIT : 编辑

Here is the code in more detail: 这是更详细的代码:

int buffer[MAX_EVENTS*2];
int bufferIndex = 0;
int eventsReturned = 0;

BufferObject *pNewBuffer;

while (bPollData)
{
    read_data(buffer[bufferIndex], &eventsReturned);

    bufferIndex += eventsReturned;

    if (bufferIndex >= MAX_EVENTS)
    {
        pNewBuffer = new BufferObject(buffer, bufferIndex);

        myList.AddTail(pNewBuffer);

        bufferIndex = 0;
    }

    Sleep(5);
}

...
... 

class BufferObject {
    int *buffer;
    int bufferSize;
public:
    BufferObject(int* source, int size)
    {
        buffer = new int[size];
        bufferSize = size;
        memcpy(buffer, source, size);
    }
};
   Sleep(5);

Well, that is 99% of your problem right there. 好吧,那就是您问题的99%。 You already know that you have a problem when your code runs fast. 您已经知道在代码快速运行时会遇到问题。 You artificially slowed it down to put a band-aid on the bug. 您人为地放慢了速度,以便对错误进行创可贴。 But of course should not be surprised that it breaks again when you do something else that makes your code run faster. 但是,当您执行其他使代码运行更快的操作时,它再次中断当然不会感到惊讶。 Like not running it with a debugger attached. 就像不使用调试器运行它一样。

You probably don't even know for a fact that 5 is adequate. 您甚至可能不知道5足够。 It is a pretty random number and the amount of time your program will actually sleep is very rarely exactly 5 milliseconds. 这是一个相当随机的数字,程序实际上进入睡眠的时间很少是5毫秒。 Default sleep accuracy is 15.625 msec but that can change when another program calls timeBeginPeriod(). 默认睡眠精度为15.625毫秒,但是当另一个程序调用timeBeginPeriod()时,该精度可能会改变。 Just running a browser is enough, Chrome notoriously changes the interrupt rate. 仅仅运行浏览器就足够了,Chrome臭名昭著地改变了中断率。 So instead of 15 msec you suddenly run 3 times faster. 因此,您突然运行了3倍,而不是15毫秒。 Breaking your program. 破坏程序。 You don't want Chrome to break your program ;) 您不希望Chrome破坏您的程序;)

You have to tackle the real problem. 您必须解决真正的问题。 Which surely is something like you just taking however many bytes the device sent you and putting it in a BufferObject. 当然,这就像您只是占用设备发送给您的字节数并将其放入BufferObject一样。 So if your program runs fast, you get many buffer objects, each with but a little bit of data. 因此,如果您的程序运行速度很快,您将获得许多缓冲区对象,每个缓冲区对象仅包含少量数据。 That can cause havoc on whatever code that consumes the data. 这可能会破坏使用数据的任何代码。 A traditional problem is the UI of the program going catatonic, madly trying to keep up with the required repaints. 一个传统的问题是该程序的UI发生阳离子变化,疯狂地试图跟上所需的重绘。

Without nearly enough insight from the question, a random guess is that you must buffer the device response first until it accumulated enough bytes to make it worthwhile to stick it in a BufferObject. 在没有足够的洞察力的情况下,一个随机的猜测是,您必须首先缓冲设备响应,直到它积累了足够的字节,才值得将其粘贴到BufferObject中。 If you continue with the Sleep() band-aid then pick a sleep amount that's an integer multiple of 15.625 rounded down. 如果继续使用Sleep()创可贴,则选择一个睡眠量,它是15.625的整数倍。 Like 15, 31, 46. 例如15、31、46。

You're likely suffering from lack of synchronisation between the thread that is collecting the data (and building the list of buffers) and the thread that the application uses to access (and presumably remove) the buffers. 您可能在收集数据(并建立缓冲区列表)的线程与应用程序用来访问(并可能删除)缓冲区的线程之间缺乏同步。

You likely need to include some locking around access to the buffer list. 您可能需要对访问缓冲区列表进行一些锁定。 It seems that you have an "active" buffer which only the data reader thread can write into (buffer) and when this is full you copy this data into a new buffer object and add it to the list. 似乎您有一个“活动”缓冲区,只有数据读取器线程可以将其写入(缓冲区),当缓冲区满时,您可以将此数据复制到新的缓冲区对象中并将其添加到列表中。 You should likely lock around the use of the list (the list may include correct synchronisation internally but it's unclear from your code example). 您应该锁定列表的使用范围(列表可能在内部包含正确的同步,但是从您的代码示例中尚不清楚)。

There appears to be no way for the loop to inform the read_data() function of the remaining space in the buffer it passes in, this may be a cause of memory overruns which could be causing problems. 循环似乎无法将传入的缓冲区中的剩余空间告知read_data()函数,这可能是导致内存溢出的原因,这可能会引起问题。

Personally, since you're dynamically allocating buffer objects anyway, I'd skip the memory copy entirely and simply hold an active buffer object and read into that directly rather than into a temporary buffer which you then copy into a buffer object. 就个人而言,由于无论如何您都是动态分配缓冲区对象,因此我将完全跳过内存副本,而只是持有一个活动缓冲区对象并直接读入该缓冲区,而不是读入一个临时缓冲区,然后再将其复制到缓冲区对象中。

It's impossible to do more than guess given the nature of the question and the lack of code. 考虑到问题的性质和缺乏代码,要做的事情只能是猜测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Visual Studio单元测试运行正常,MSTEST不能正常运行 - Visual Studio Unit Test runs fine, MSTEST does not Visual Studio C# 创建句柄时出错,但构建的应用程序运行正常 - Visual Studio C# Error creating handle but built app runs fine LinqPad查询运行正常,但由于在Visual Studio中运行Linq to Entities错误而失败 - LinqPad query runs fine, but fails with Linq to Entities error running in visual studio Visual Studio设计器不会显示我的用户控件,但可以正常运行应用程序 - Visual studio designer wont display my user controls but runs the application fine 如果调试文件夹的其余部分可用,但不是独立的,我的 EXE 运行良好 - My EXE runs fine if it has the rest of the debug folder available, but not standalone 程序运行正常,直到将其转换为服务为止 - Program Runs Fine until I turn it into a Service C# 程序运行良好,直到最小化 - C# Program runs fine, until minimized Visual Studio 2010程序在Win 7 32位上运行时,接口未注册错误 - Interface Not Registered error when Visual Studio 2010 program runs on Win 7 32bit C#-Visual Studio在运行时崩溃,在外部运行已编译程序的效果很好 - C# - Visual Studio crashes at runtime, running the compiled program externally works fine 安装Microsoft.Azure.SignalR.AspNet会导致在部署到服务器时方法未实现运行时错误,但在Visual Studio 2017上运行良好 - Installing Microsoft.Azure.SignalR.AspNet causes method not implemented runtime error when deployed to a server but runs fine on Visual Studio 2017
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM