2014-12-25 7 views
3

У меня есть поток, который вызывает статический метод для обновления свойств файла с помощью WindowsAPICodePack ShellPropertyWriter и BackgroundWorker. Нить вызывает метод ниже для каждого файла в папке из 1000+ файлов и зависает на ShellPropertyWriter.close() после 700-го обновления или так далее.C# thread зависает в закрытом файле

Ничего общего с самим файлом, попробовал использовать разные файлы, которые были успешно обновлены до этого.

public static bool ShellPropertyUpdate(VideoEntry mediaEntry) 
    { 
     try 
     { 
      ShellFile mediafile = ShellFile.FromFilePath(mediaEntry.FilePath); 
      ShellPropertyWriter pw = mediafile.Properties.GetPropertyWriter(); 
      pw.WriteProperty(SystemProperties.System.Music.Artist, mediaEntry.Actor); 
      pw.WriteProperty(SystemProperties.System.Music.Genre, mediaEntry.Genre); 
      pw.WriteProperty(SystemProperties.System.Rating, mediaEntry.Rating); 
      pw.Close(); 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
     return true; 
    } 

    private void mnuWriteMetadataToFiles_Click(object sender, EventArgs ev) 
    { 
     this.WorkerThread = new BackgroundWorker(); 
     this.WorkerThread.DoWork += new DoWorkEventHandler(WorkerThread_WriteMetadataToFiles); 
     this.WorkerThread.ProgressChanged += new ProgressChangedEventHandler(WorkerThread_ProgressChanged); 
     this.WorkerThread.RunWorkerCompleted += (s, e) => WorkerThread_Completed("Writing metadata to files", s, e); 
     this.WorkerThread.WorkerReportsProgress = true; 
     this.WorkerThread.WorkerSupportsCancellation = true; 
     this.WorkerThread.RunWorkerAsync(WMPlayer); 
    } 

    private void WorkerThread_WriteMetadataToFiles(object sender, DoWorkEventArgs e) 
    { 
     int counter = 0; 
     BackgroundWorker worker = (BackgroundWorker)sender; 
     MediaPlayer wmp = (MediaPlayer)e.Argument; 

     // ... Loop with the foreach video in the library and write it to file. 
     foreach (VideoEntry entry in wmp.Videos) 
     { 
      if (worker.CancellationPending) 
      { 
       e.Cancel = true; 
      } 
      else 
      { 
       worker.ReportProgress(counter, "Updating '" + entry.Filename + "'" + Environment.NewLine + "Processing file"); 
       if (VideoToFile.ShellPropertyUpdate(entry)) 
       { 
        result &= true; 
       } 
       counter++; 
      } 
     } 
     e.Result = result; 
    } 
+0

Хороший вопрос. Можете ли вы воспроизвести его каждый раз? Любая разница с режимами Debug vs Release? Whats вызывающий код, просто «foreach (файл в каталоге»? Можете ли вы положить крошечный «Thread.Sleep (50)» и сообщить нам, если это имеет значение? Работает ли он на основном потоке? корреляция с размерами файлов там, где висит нить? –

+0

Я не уверен, будет ли эта информация достаточной для устранения неполадок. Я имею в виду, что пакет API имеет ошибку. Но также возможно, что ошибка в вашем коде в другом месте, о котором мы не видим выше .. Код, который вы использовали, кажется довольно простым. Не глядя на остальную часть кода, либо ваш, либо пакет API, трудно сказать. ИМХО, вы бы получайте в основном догадки, если вы не добавите больше деталей. –

+0

Я могу воспроизводить его каждый раз, и он зависает или бит после или до обновления файла 700. Я нахожусь в Debug x86 (попробую Release). Вызывающий код прокручивается для каждого в списке . Я попробую спать и основную тему и дам вам знать. с файлом из того, что я видел, я попытался обменять разные файлы в списке и получил тот же конечный результат. Я уверен, что ошибка в моем коде где-то, поскольку я использую TagLib для обновления тегов ID3v2, и те же результаты возникают при закрытии файла там два, но происходит примерно с 300 + обновлениями. Я добавлю код вызова выше. – zcodemonkey

ответ

3

Никогда не слышал об этом собрании раньше, но он пахнет усталостью рук для меня. Попробуйте это вместо:

Здесь каждый дескриптор файла закрывается немедленно, а не по усмотрению сборщика мусора. ShellFile должен реализовать IDisposable, чтобы это сработало, иначе этот код не будет компилироваться. Я уверен, что ShellFile реализует его.

+0

ShellFile реализует IDisposable. Я просто попробовал, но, к сожалению, это не сработало, так же по-прежнему. это более чистый способ реализовать метод в любом случае. спасибо – zcodemonkey

+0

По-видимому, это как-то связано с самими файлами. Я достал несколько проблемных файлов, и Thread продолжил обработку до следующего файла проблемы. Я не знаю, что не так с файлом, однако я готов перейти к обновлению проблемных файлов. Есть ли способ остановить/убить поток? Я не могу использовать DoWorkEventArgs.cancel(), так как поток висит и не возвращается. – zcodemonkey

+0

@stackmonkey приятно, и вы должны сделать ответ и принять его. – Dialecticus

0

По-видимому, это как-то связано с самими файлами. Я достал несколько проблемных файлов, и Thread продолжил обработку до следующего файла проблемы. Я не знаю, что не так с файлом, однако я готов перейти к обновлению проблемных файлов. Есть ли способ остановить/убить поток? Я не могу использовать DoWorkEventArgs.cancel(), так как поток висит и не возвращается.

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