Проблема приложения C # только в Release build - PullRequest
1 голос
/ 14 марта 2011

проблема появляется только при сборке релиза и запуске exe-файла (не из Visual Studio) во всех остальных сочетаниях - либо из Visual Studio, либо из exe - все работает нормально

Я использую функцию Load с помощью backgroundWorker

Нагрузка:

while (!Request.GAMELIST.XMLReceived) ;

GameEngine.ParseGameList( Request.GAMELIST.XML );

Request.GAMELIST.XMLReceived = false;

цикл в этом фрагменте работает как задержка он должен дождаться получения XML от сервера и затем продолжить но он застрял в указанной выше ситуации

если я поставлю MessageBox.show («поехали»); после цикла MessageBox не появится но если я поставлю MessageBox.show («поехали»); перед тем как цикл приложение будет получать данные, пока я не нажму на окно сообщения и тогда все будет работать нормально

вот реализация класса 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;
    }
}

пожалуйста, предоставьте помощь, если можете это действительно странная вещь, которую я сам не могу понять

Спасибо.

Ответы [ 2 ]

4 голосов
/ 14 марта 2011

Да, этот код имеет очень хорошие шансы повесить в сборке Release.Оптимизатор JIT не знает, что переменная может быть установлена ​​в true кодом вне метода.Вы должны сказать ему, что, например так:

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

Ключевое слово volatile гарантирует, что джиттер не сохранит значение переменной в регистре процессора.

Это решает вашу проблему, оновсе еще не правильный способ сделать это.Вместо этого вы должны использовать AutoResetEvent.Это гарантирует, что поток реагирует на изменение переменной максимально быстро.И самое главное, он позволяет блокировать поток, чтобы он не записывал циклы процессора.

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 );
2 голосов
/ 14 марта 2011

Это плохо идея:

while (!Request.GAMELIST.XMLReceived) ;

По крайней мере, вы должны делать что-то вроде:

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

Ваша программа работает нормально в режиме отладки, возможно, из-за определенных процедур отладки, добавленных в цикл while, что делает ее работу медленнее ...

...