2010-01-29 3 views
3

Я написал утилиту, которая ищет файлы журналов для исключений, и она отлично справилась с Vista 64 бит. Теперь я обновил до 64-разрядных версий Windows 7, и иногда это можно зависать при чтении файла. Я думаю, что он зависает, только если файл журнала активен, и пользователь пишет ему. Но это работает отлично, поскольку я использую флаг fmShareDenyNone. Я использую Delphi 2007. Любая идея, что я могу изменить, чтобы сделать эту работу?Изменено поведение для filestream с Windows 7?

Вот весь метод поиска в каталогах для логах:

procedure TfrmMain.Refresh; 
var 
    FileData : TSearchRec; // Used for the file searching. Contains data of the file 
    vPos, i, PathIndex : Integer; 
    vCurrentFile: TStringList; 
    vDate: TDateTime; 
    vFileStream: TFileStream; 
begin 
    tvMain.DataController.RecordCount := 0; 
    vCurrentFile := TStringList.Create; 
    memCallStack.Clear; 

    try 
    for PathIndex := 0 to fPathList.Count - 1 do      // Loop 0. This loops until all directories are searched through 
    begin 
     if (FindFirst (fPathList[PathIndex] + '\*.log', faAnyFile, FileData) = 0) then 
     repeat              // Loop 1. This loops while there are .log files in Folder (CurrentPath) 
     vDate := FileDateToDateTime(FileData.Time); 

     if chkLogNames.Items[PathIndex].Checked and FileDateInInterval(vDate) then 
     begin 
      tvMain.BeginUpdate;  // To speed up the grid - delays the guichange until EndUpdate 

      fPathPlusFile := fPathList[PathIndex] + '\' + FileData.Name; 
      vFileStream := TFileStream.Create(fPathPlusFile, fmShareDenyNone); 
      vCurrentFile.LoadFromStream(vFileStream); 

      fUser := FindDataInRow(vCurrentFile[0], 'User');   // FindData Returns the string after 'User' until ' ' 
      fComputer := FindDataInRow(vCurrentFile[0], 'Computer'); // FindData Returns the string after 'Computer' until ' ' 

      Application.ProcessMessages;     // Give some priority to the User Interface 

      if not CancelForm.IsCanceled then 
      begin 
      CancelForm.lblLogFile.Caption := fPathPlusFile; 
      if rdException.Checked then 
       for i := 0 to vCurrentFile.Count - 1 do 
       begin 
       vPos := AnsiPos(MainExceptionToFind, vCurrentFile[i]); 
       if vPos > 0 then 
        UpdateView(vCurrentFile[i], i, MainException); 

       vPos := AnsiPos(ExceptionHintToFind, vCurrentFile[i]); 
       if vPos > 0 then 
        UpdateView(vCurrentFile[i], i, HintException); 
       end 
      else if rdOtherText.Checked then 
       for i := 0 to vCurrentFile.Count - 1 do 
       begin 
       vPos := AnsiPos(txtTextToSearch.Text, vCurrentFile[i]); 
       if vPos > 0 then 
        UpdateView(vCurrentFile[i], i, TextSearch) 
       end 
      end; 

      vFileStream.Destroy; 
      tvMain.EndUpdate;  // Now the Gui can be updated 
     end; 
     until(FindNext(FileData) <> 0) or (CancelForm.IsCanceled);  // End Loop 1 
    end;               // End Loop 0 
    finally 
    FreeAndNil(vCurrentFile); 
    end; 
end; 
+1

Первое, что вам нужно сделать, это реорганизовать код пользовательского интерфейса из реальной логики. Избавьтесь от tvMain, UpdateView, memCallStack, Application.ProcessMessages, CancelForm, FindDataInRow. Полученный код должен быть намного короче и легче воспроизвести. –

+0

Да, я согласен с этим. Это началось как быстрый и грязный инструмент вместо поиска logdirs вручную. Но он стал полезным и для разработчиков, и для поддержки. –

+2

Когда приложение появляется в зависании, нажмите кнопку «пауза» в отладчике, чтобы узнать, где именно он висит. Вы сказали, что это зависает, когда «читает поток», но потом вы говорите о режиме совместного доступа. Если общий доступ был релевантным, тогда ваша программа зависала бы при открытии * файла, а не при чтении. Стол вызовов вашей приостановленной программы сообщит вам, где это происходит. –

ответ

5

Быстрый выстрел: Если у вас есть файл, который написан довольно часто, как в лог-файл, вы должны отключить индексирование содержимого для этого файл. В противном случае служба индексатора Windows будет постоянно переиндексировать этот файл и тем самым блокировать любой другой запрос.

Вы можете найти атрибут индексации контекста в разделе «Свойства файла» - «расширенные атрибуты».

IMHO это было не лучшее решение от Microsoft, чтобы включить индексирование контента в Windows 7 по умолчанию.

+0

Доступ к файлам журналов осуществляется с помощью обмена файлами и находится на сервере с Windows Server 2003. Я проверил его, и на самом деле сервер индексируется для каталога журнала. Я выключаю его, чтобы увидеть, есть ли у него какие-либо улучшения. Спасибо за совет! –

+0

Windows по умолчанию обрабатывает только пользовательские файлы (мне приходилось включать и вручную включать все остальные местоположения, я хочу, чтобы индексирование контента с включенной поддержкой Microsoft по умолчанию) - по умолчанию он не сканирует папку, которую разработчик напишет файл журнала. –

Смежные вопросы