Атрибутом webmethod медленнее по исполнению, чем приложения Windows один и тот же код


Я разработали приложение, которое взаимодействует с IBM пространства clearquest. Проблема в том, что когда я запускаю все на месте, такие как, запуск веб-сервиса, а затем ASP-страницы местных, все это на скорости я ожидал. Когда я выкладываю вебсервис (скомпилированных) на сервер и запустить веб-страницу через сервер, вызов веб-метод принимает по крайней мере 10 раз количество времени, он должен. Я не знаю, почему это происходит. Я сделал консольное приложение, которое имеет функцию и выполняет его на сервере и локально, и обе они возвращают то же количество времени (ориентировочно). Просто когда я двигаюсь к исполнению через веб-метод, который все перемалывает в темпе улитки.

Любые идеи? Это происходит каждый раз, не только по первому зову.

Может быть, анализ кода может помочь здесь?

Атрибутом webmethod (глаг):

Public Function RetrieveQueryResults(ByRef cqSession As ClearQuestOleServer.Session, _
                                     ByVal sqlStmt As String) As List(Of SearchResultsSingleIssue)

Dim numCols As Integer, status As Integer, columnIdx As Integer
Dim numRows As Integer
Dim rowContents As String = ""
Dim colValue As New Object
Dim colLabel As New Object
Dim allitems As New List(Of SearchResultsSingleIssue)
Dim results As New SearchResultsSingleIssue
Dim cqResultSet As ClearQuestOleServer.OAdResultset

cqResultSet = cqSession.BuildSQLQuery(sqlStmt)
cqResultSet.Execute()

' Get the number of columns returned by the query.
numRows = 0
numCols = cqResultSet.GetNumberOfColumns
status = cqResultSet.MoveNext


' Collect query results.
Do While status = AD_SUCCESS
    results = New SearchResultsSingleIssue
    numRows = numRows + 1

    For columnIdx = 1 To numCols

        colLabel = cqResultSet.GetColumnLabel(columnIdx)
        colValue = cqResultSet.GetColumnValue(columnIdx)

        'Make sure that we dont pass along a null reference
        If colValue = Nothing Then
            colValue = ""
        End If

        Select Case colLabel
            Case "ID"
                results.IssueID = colValue
            Case "HEADLINE"
                results.Headline = colValue
            Case "NAME"
                results.State = colValue
            Case "OE_CONTACT"
                results.OEContact = colValue
            Case "DESCRIPTION"
                results.Further_Description = colValue
            Case "PRODUCT_NAME"
                results.Product_Name = colValue
            Case "FUNCTIONAL_AREA"
                results.Functional_Area = colValue
            Case "SUBTOPIC"
                results.Subtopic = colValue
            Case "FOUND_VERSION"
                results.Found_In = colValue
            Case "SCHEDULED_VERSION"
                results.Scheduled_For = colValue
            Case "SYMPTOMS"
                results.Symptoms = colValue
            Case "AFFECTED_SYSTEMS"
                results.Affected_System_Types = colValue
            Case "ISSUE_TYPE"
                results.Issue_Type = colValue
            Case "ASSIGNED_TO"
                results.Assigned_Developer = colValue
            Case "TESTED_BY"
                results.Assigned_Tester = colValue
            Case "BUILT_VERSION"
                results.Built_In = colValue
            Case "TESTED_VERSION"
                results.Tested_In = colValue
            Case "NOTES_LOG"
                results.Notes_Log = colValue
            Case "CUSTOMER_SEVERITY"
                results.Severity = colValue
            Case "PRIORITY"
                results.Priority = colValue

        End Select

    Next columnIdx

    ' Add the query row result to the compiled list of all rows.
    allitems.Add(results)
    status = cqResultSet.MoveNext

Loop

Return allitems

End Function

Метод Локального Приложения Windows (На C#):

private void button2_Click(object sender, EventArgs e)
{
    start = DateTime.Now.TimeOfDay.Seconds;

    int numCols = 0;
    int status = 0;
    int columnIdx = 0;
    int numRows = 0;
    string rowContents = "";
    string colValue;
    string colLabel;
    List<SearchResultsSingleIssue> allitems = new List<SearchResultsSingleIssue>();
    SearchResultsSingleIssue results = new SearchResultsSingleIssue();
    ClearQuestOleServer.OAdResultset cqResultSet = default(ClearQuestOleServer.OAdResultset);

    cqResultSet = (ClearQuestOleServer.OAdResultset)ClearQuestSession.BuildSQLQuery(sqlStatement); 
    cqResultSet.Execute();

    // Get the number of columns returned by the query.
    numRows = 0;
    numCols = cqResultSet.GetNumberOfColumns();
    status = cqResultSet.MoveNext();


    // Collect query results.
    while (status == 1)
    {
        results = new SearchResultsSingleIssue();
        numRows = numRows + 1;


        for (columnIdx = 1; columnIdx <= numCols; columnIdx++)
        {
            colLabel = (string)cqResultSet.GetColumnLabel(columnIdx);
            colValue = (string)cqResultSet.GetColumnValue(columnIdx);
            //Make sure that we dont pass along a null reference
            if (colValue == null)
            {
                colValue = "";
            }

            switch (colLabel)
            {
                case "ID":
                    results.IssueID = colValue;
                    break;
                case "HEADLINE":
                    results.Headline = colValue;
                    break;
                case "NAME":
                    results.State = colValue;
                    break;
                case "OE_CONTACT":
                    results.OEContact = colValue;
                    break;
                case "DESCRIPTION":
                    results.Further_Description = colValue;
                    break;
                case "PRODUCT_NAME":
                    results.Product_Name = colValue;
                    break;
                case "FUNCTIONAL_AREA":
                    results.Functional_Area = colValue;
                    break;
                case "SUBTOPIC":
                    results.Subtopic = colValue;
                    break;
                case "FOUND_VERSION":
                    results.Found_In = colValue;
                    break;
                case "SCHEDULED_VERSION":
                    results.Scheduled_For = colValue;
                    break;
                case "SYMPTOMS":
                    results.Symptoms = colValue;
                    break;
                case "AFFECTED_SYSTEMS":
                    results.Affected_System_Types = colValue;
                    break;
                case "ISSUE_TYPE":
                    results.Issue_Type = colValue;
                    break;
                case "ASSIGNED_TO":
                    results.Assigned_Developer = colValue;
                    break;
                case "TESTED_BY":
                    results.Assigned_Tester = colValue;
                    break;
                case "BUILT_VERSION":
                    results.Built_In = colValue;
                    break;
                case "TESTED_VERSION":
                    results.Tested_In = colValue;
                    break;
                case "NOTES_LOG":
                    results.Notes_Log = colValue;
                    break;
                case "CUSTOMER_SEVERITY":
                    results.Severity = colValue;
                    break;
                case "PRIORITY":
                    results.Priority = colValue;

                    break;
            }

        }

        // Add the query row result to the compiled list of all rows.
        allitems.Add(results);
        status = cqResultSet.MoveNext();


    }

    seconds = (DateTime.Now.TimeOfDay.Seconds - start);
    label3.Text = seconds.ToString();



}

Код выполняется в о...6 секунд.



585
4
задан 11 марта 2011 в 10:03 Источник Поделиться
Комментарии
1 ответ

Это старейший зомби на сайте, я думал, что код мог бы использовать немного обзора. Я не думаю, что я могу ответить на вопрос о том, хотя странные проблемы с производительностью.


Глаг

Объявления

Вы не согласуется с вашим стилем объявление:

Dim numCols As Integer, status As Integer, columnIdx As Integer

Хотя это правильно и избежать распространенной ошибки только объявления типа до последнего переменная, объявленная, мне не нравятся несколько объявлений на одной линии. Это более читабельным, когда они расстались. Эти три объявляется в той же строке, только кажется произвольным.

Переменные должны быть объявлены как можно ближе к их использования, этот блок объявлений в верхней части ваш способ не помогает читабельности либо.

Эта линия служит никакой цели и могут быть устранены:

numRows = 0

Петли

Вы извлекаете первый результат перед итерации результирующий набор:

status = cqResultSet.MoveNext

' Collect query results.
Do While status = AD_SUCCESS

И тогда ваш цикл заканчивается так:

    status = cqResultSet.MoveNext
Loop

Я думаю, что вы можете ликвидировать статус идентификатор вместе с первой проверки, и сделать это вместо:

Do While cqResultSet.MoveNext = AD_SUCCESS

Петли не нужно, чтобы войти в Выбор блока, если colValue это ничего - я больше на C# парень, так что это может быть неправильно, но я думаю, что дальше сайта могут быть использованы здесь, чтобы пропустить итерацию тут:

'Make sure that we dont pass along a null reference
If colValue = Nothing Then Continue

Не уверен, что мне нравится выбор здесь, и я не уверен, что цикл снова возвращается столбцах покупка вас чем-либо. Я не знаю этот API, но если бы это было ADO.NET я рекомендую вам получить значение для каждого столбца имя и присвоить его результат , если столбец не существует, вроде этого (синтаксис-это, наверное, неправильно, и к C#, но вы получите идею):

if (cqResultSet["ID"] != null) results.IssueId = cqResultSet["ID"].Value;

Смысл в том, что вы в любом случае наименования всех столбцов и всех свойств, поэтому петли+переключатель не покупать у вас ничего, кроме нужно теперь отслеживать, что индекс столбца, в котором вы.

Именования

Я не люблю подчеркивания в идентификаторах. Придерживаться Конвенции PascalCase, будьте последовательны. Также результаты будут лучше имя для allItems (возврат allItems будет обратный результат), а результат будет лучше назвать результаты (allItems.Добавить(результаты) становится результаты.Добавить(результат)).

Если AD_SUCCESS - это код состояния, это название заставляет меня думать, что это константа. Однако статус коды-это набор тесно связанных констант, как правило, взаимоисключающие друг друга - это похоже на работу для перечисления.


В C#

Большинство из вышеперечисленного относится и к C# код. Как сниппеты делать то же самое и код примерно выглядит эквиваленте, так что я буду держать этот отзыв сушит и не упомяну, чтобы объявлять переменные как можно ближе к местам их использования ;)

while (status == 1)

Что случилось с постоянной? Волшебные цифры менее волшебный в C#, чем в VB?

Сроки

Ты контролируешь свой код так, как в VB6, в обоих фрагментах. Взглянуть на секундомер класса, который намного лучше в такого рода задач (будь то только на ElapsedMilliseconds собственность!).

6
ответ дан 13 февраля 2014 в 04:02 Источник Поделиться