仅发布版本中的 C# 应用程序问题

发布于 2024-10-21 17:19:34 字数 922 浏览 7 评论 0原文

该问题仅在进行发布构建并运行 exe 文件时出现(不是来自 Visual Studio) 在所有其他组合中,无论是从 Visual Studio 运行还是运行 exe,一切都正常

我正在使用 backgroundWorker Load 运行 Function

Load:

while (!Request.GAMELIST.XMLReceived) ;

GameEngine.ParseGameList( Request.GAMELIST.XML );

Request.GAMELIST.XMLReceived = false;

此片段中的 while 循环就像延迟一样 它应该等到从服务器收到 XML,然后继续 但

如果我将 MessageBox.show("here we go"); 放在上面指定的情况下,它就会卡住while 循环之后 消息框不会出现 但如果我把 MessageBox.show("here we go"); while 循环之前 应用程序将接收数据,直到我单击“消息框确定” 然后一切都会正常工作,

这里是 GAMELIST 类实现,

public class RequestGAMELIST
{
    public string XML;

    public bool XMLReceived = false;

    public void ParseRequest( string request )
    {
        int index = request.IndexOf(':') + 2;
        XML = request.Substring(index, request.Length - index);
        XMLReceived = true;
    }
}

如果可以的话请提供帮助 这真的很奇怪,我自己无法弄清楚,

谢谢。

the problem only appears when making Release build and running exe file ( not from visual studio )
in all other combination either it's running from visual studio or running exe everything works fine

I'm running Function Load using backgroundWorker

Load:

while (!Request.GAMELIST.XMLReceived) ;

GameEngine.ParseGameList( Request.GAMELIST.XML );

Request.GAMELIST.XMLReceived = false;

while loop in this fragment works like delay
it should wait till XML is received from server and then continue
but it stucks in above specified situation

if I'll put MessageBox.show("here we go"); after while loop
messageBox will not appear
but if I'll put MessageBox.show("here we go"); before while loop
application will receive data until I click messagebox ok
and then everything will work fine

here is GAMELIST class implementation

public class RequestGAMELIST
{
    public string XML;

    public bool XMLReceived = false;

    public void ParseRequest( string request )
    {
        int index = request.IndexOf(':') + 2;
        XML = request.Substring(index, request.Length - index);
        XMLReceived = true;
    }
}

please provide help if you can
this is really strange thing which I can't figure out by my self

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡莣 2024-10-28 17:19:34

是的,这段代码很有可能挂在发布版本中。 JIT 优化器不知道该变量可能被方法外部的代码设置为 true。您需要这样告诉它:

public class RequestGAMELIST
{
    public volatile bool XMLReceived = false;
    // etc..
}

volatile 关键字确保抖动不会将变量值存储在 CPU 寄存器中。

这解决了你的问题,但这仍然不是正确的方法。您应该改用 AutoResetEvent。它确保线程尽可能快地响应变量更改。最重要的是,它让线程阻塞,这样就不会消耗任何 cpu 周期。

public class RequestGAMELIST
{
    public AutoResetEvent XMLReceived = new AutoResetEvent();

    public void ParseRequest( string request )
    {
        int index = request.IndexOf(':') + 2;
        XML = request.Substring(index, request.Length - index);
        XMLReceived.Set();
    }

}

在你的线程中:

    XMLReceived.WaitOne();
    GameEngine.ParseGameList( Request.GAMELIST.XML );

Yes, this code has very good odds to hang in the Release build. The JIT optimizer doesn't know that the variable might be set to true by code outside of the method. You need to tell it that, like this:

public class RequestGAMELIST
{
    public volatile bool XMLReceived = false;
    // etc..
}

The volatile keyword ensures that the jitter won't store the variable value in a CPU register.

That solves your problem, it is still not the right way to do it. You should use an AutoResetEvent instead. It ensures that the thread responds to the variable change is quickly as possible. And most importantly, it lets the thread block so it doesn't burn any cpu cycles.

public class RequestGAMELIST
{
    public AutoResetEvent XMLReceived = new AutoResetEvent();

    public void ParseRequest( string request )
    {
        int index = request.IndexOf(':') + 2;
        XML = request.Substring(index, request.Length - index);
        XMLReceived.Set();
    }

}

In your thread:

    XMLReceived.WaitOne();
    GameEngine.ParseGameList( Request.GAMELIST.XML );
你的背包 2024-10-28 17:19:34

这是一个想法:

while (!Request.GAMELIST.XMLReceived) ;

至少你应该这样做:

while (!Request.GAMELIST.XMLReceived) {
  System.Threading.Thread.Sleep(100);  // Don't hog the CPU!
}

你的程序在调试模式下运行良好,可能是由于在 while 循环中添加了某些调试例程,这使得它运行得更慢......

This is a bad idea:

while (!Request.GAMELIST.XMLReceived) ;

At least you should be doing something like:

while (!Request.GAMELIST.XMLReceived) {
  System.Threading.Thread.Sleep(100);  // Don't hog the CPU!
}

Your program runs fine in debug mode perhaps due to certain debug routines added inside the while loop which makes it run slower...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文