Как интерпретировать трассировку стека с + в номерах строк (ASP.NET) [дубликат]

Новые Thread и решения AsyncTask уже объяснены.

AsyncTask в идеале следует использовать для коротких операций. Обычный Thread не является предпочтительным для Android.

Посмотрите альтернативное решение, используя HandlerThread и Обработчик

HandlerThread

Handy класс для запуска нового потока, который имеет петлитель. Затем петлитель можно использовать для создания классов обработчиков. Обратите внимание, что еще нужно вызвать start().

Обработчик:

Обработчик позволяет отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока , Каждый экземпляр Handler связан с одним потоком и очередью сообщений этого потока. Когда вы создаете нового обработчика, он привязан к очереди потоков / сообщений потока, который его создает - с этой точки он будет доставлять сообщения и исполняемые файлы в очередь сообщений и выполнять их по мере их выхода из сообщения

Решение:

  1. Создать HandlerThread
  2. Вызов start() на HandlerThread
  3. Создайте Handler, получив Looper из HanlerThread
  4. Вставьте код связанного с вашей сетью объекта Runnable
  5. Отправьте задание Runnable на Handler

Пример фрагмента кода, адрес NetworkOnMainThreadException

HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());

Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        try {
            Log.d("Ravi", "Before IO call");
            URL page = new URL("http://www.google.com");
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ( (line =  buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Ravi", "After IO call");
            Log.d("Ravi",text.toString());

        }catch( Exception err){
            err.printStackTrace();
        }
    }
};
mainHandler.post(myRunnable);

Плюсы использования этого подхода:

  1. Создание нового Thread/AsyncTask для каждая операция сети стоит дорого. Thread/AsyncTask будет уничтожен и повторно создан для следующих сетевых операций. Но с подходами Handler и HandlerThread вы можете отправить множество сетевых операций (как выполняемых задач) в одиночный HandlerThread с помощью Handler.

28
задан Mustafa Ekici 23 March 2014 в 00:04
поделиться

10 ответов

Попробуйте этот простой хак:

Сначала добавьте этот класс (расширение) в ваше пространство имен (большинство из них должно быть класс верхнего уровня):

public static class ExceptionHelper
{
    public static int LineNumber(this Exception e)
    {

        int linenum = 0;
        try
        {
            //linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(":line") + 5));

            //For Localized Visual Studio ... In other languages stack trace  doesn't end with ":Line 12"
            linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(' ')));

        }


        catch
        {
            //Stack trace is not available!
        }
        return linenum;
    }
}

И его сделано! Используйте метод LineNumber когда вам это нужно:

try
{
//Do your code here
}
catch (Exception e)
{
int linenum = e.LineNumber();
}
20
ответ дан Ricardo LR 24 August 2018 в 03:58
поделиться

Вот довольно простой способ получить кучу информации из объекта Exception: просто добавьте такой код к любым потенциальным методам исключения:

catch (Exception ex)
{
    String exDetail = String.Format(ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
    MessageBox.Show(exDetail);
}

Информация, которую вы получите, будет часто больше особенно в отношении номеров строк, где возникают проблемы, чем вы могли бы видеть.

Возможно, вы заметили, что String.Format () использует константу, а именно «ExceptionFormatString». Это хорошая практика, поэтому, если вы хотите ее изменить, добавив вышеприведенный код в 40-eleven methods, вы можете просто изменить его на одно место. Во всяком случае, вот он:

public static readonly String ExceptionFormatString = "Exception message: {0}{1}Exception Source: {2}{1}Exception StackTrace: {3}{1}";

Счастливая отладка!

2
ответ дан B. Clay Shannon 24 August 2018 в 03:58
поделиться

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

System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());

Однако исключение not происходит из вы пишете ExecuteNonQuery, но где-то внутри этой функции, возможно, несколько кадров стека (т.е. вложенные вызовы функций) глубже. Таким образом, первый кадр (который вы явно извлекаете с помощью GetFrame(0)) находится где-то внутри кода Microsoft (скорее всего, System.Data.dll), для которого у вас нет отладочных символов.

Выписать полное исключение stacktrace в вашей функции, чтобы увидеть, что я имею в виду:

try
{
   // your code ...
}
catch (Exception ex) 
{
   Console.WriteLine(ex);
}

. Коротко синтаксический анализ stacktrace (т.е. ex.StackTrace) нет надежной причины для получения номера строки вызова ExecuteNonQuery (). Я особенно хотел бы not попытаться подсчитать стековые кадры вверх по стеку, где происходит ваш вызов ExecuteNonQuery ().

Интересно, однако, что вам нужно только для linenumber, почему бы и нет log / print / независимо от того, что будет в полной стеке. По крайней мере, по причинам диагностики, которые намного полезнее.

7
ответ дан Christian.K 24 August 2018 в 03:58
поделиться

Вы можете получить 0 в результате, если вы не инициализируете StackTrace для включения fileinfo.

enter image description here [/g0]

Попробуйте это

try
{
    //code
}
catch (Exception e)
{
    var lineNumber = new System.Diagnostics.StackTrace(e, true).GetFrame(0).GetFileLineNumber();
}

Это сработало для меня.

4
ответ дан d-coder 24 August 2018 в 03:58
поделиться

попробуйте это

Чтобы получить номера строк в StackTrace, вам нужно иметь правильную информацию об отладке (файлы PDB) вместе с вашими dll / exes. Чтобы сгенерировать информацию об отладке, установите опцию в Project Properties -> Build -> Advanced -> Debug Info:

alt text [/g1]

Для этого достаточно full (см. MSDN docs для других опций). Информация об отладке (то есть файлы PDB) генерируется для конфигураций сборки Debug по умолчанию, но также может быть сгенерирована для конфигураций сборки Release.

Генерирование PDB для создания релизов позволяет отправлять вам код без PDB, но для удаления PDB рядом с DLL, если вам нужны номера строк (или даже для подключения удаленного отладчика). Следует отметить, что в сборке релизов номера строк могут быть не совсем корректными из-за оптимизации, сделанной компилятором или компилятором JIT (это особенно важно, если номера строк отображаются как 0).

8
ответ дан Enigma State 24 August 2018 в 03:58
поделиться

В .NET 4.5 вы можете использовать ExceptionDispatchInfo , чтобы восстановить ваши исключения вместо классического throw; (убедитесь, что файлы PDB там или не отображаются номера строк):

    static void A()
    {
        try
        {
            throw new Exception("A");
        }
        catch (Exception e)
        {
            ExceptionDispatchInfo.Capture(e).Throw();
        }
    }

Источник: blogpost . Файлы PDB не снижают производительность в Windows.

0
ответ дан Petre T 24 August 2018 в 03:58
поделиться

следующий метод обработчика журнала ошибок кода отлично работает:

в catch:

 catch (Exception ex)
            {
                CommonTools.vAddToLog(ex, EmpID, ErrorCodes.UnDefined);
                Response.Redirect("~/ErrorPage.aspx");
            }

в методе AddToLog:

 string _exMsgErr = string.Empty;
                var frame = oStackTrace.FrameCount > 1 ? oStackTrace.GetFrame(1) : oStackTrace.GetFrame(0);
                if (oException.GetType() == typeof(JOVALException))
                {
                    JOVALException _JOVALEx = (JOVALException)oException;
                    _exMsgErr = _JOVALEx.Message;
                }
                else
                {
                    _exMsgErr = oException.Message;
                }
                ErrorLog oError = new ErrorLog(frame.GetMethod().Name, (string)frame.GetFileName(), (int)frame.GetFileLineNumber(), sCustomErrorMessage == string.Empty ? _exMsgErr : sCustomErrorMessage, sUserID, oErrCode);
                //Cont. your code of log file

Наконец, Файл журнала xml выглядит так:

<ErrorLog>
<MethodName>FillRolesDDLs</MethodName>
<FileName>
F:\Projects\ERP\ERP\Pages\SystemSettings\Roles.aspx.cs
</FileName>
<LineNumber>61</LineNumber>
<ErrorMesssage>
The given DataRow is not in the current DataRowCollection.
</ErrorMesssage>
<UserID>1</UserID>
<ErrCode>UnDefined</ErrCode>
<Time>15/03/2015 16:23:21.976</Time>
</ErrorLog>
0
ответ дан Raed Alsaleh 24 August 2018 в 03:58
поделиться

Чтобы получить номера строк, вам нужно, чтобы ваше приложение находилось в режиме отладки или , включая символы отладки в той же папке (файл .pdb) для появления номеров строк. После этого вы создаете код, который должен быть опубликован.

1
ответ дан Rowland Shaw 24 August 2018 в 03:58
поделиться

Скопируйте всю трассировку стека в строку или stringbuilder с помощью try / catch, который может быть брошен, см. ниже пример

try
{
    //Do some programming
}
catch(Exception ex)
{

   //Catch the exception and assign the stack trace
   StackTrace = ex;
}

Выход будет

System.IndexOutOfRangeException: Index was outside the bounds of the array.   
at Program.Run() in C:\Console Application1\Program.cs:line 37    
at Program.Main(String[] args) in C:\Console Application1\Program.cs:line 45 

В первой строке отображается тип исключения и сообщение. Во второй строке отображается файл, функция и номер строки, где было выбрано исключение

-1
ответ дан Sai Kalyan Kumar Akshinthala 24 August 2018 в 03:58
поделиться

Вы можете использовать класс System.Diagnostics.StackTrace , как показано ниже:

public void MethodName()
{
    try
    {
        throw new Exception();
    }
    catch (Exception ex)
    {
        // Get stack trace for the exception with source file information
        var trace = new StackTrace(ex, true);

        // Get the top stack frame
        var frame = trace.GetFrame(0);

        // Get the line number from the stack frame
        var line = frame.GetFileLineNumber();
    }
}
4
ответ дан VS1 24 August 2018 в 03:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: