.NET TPL лямбды и замыкания - будет ли этот код работать - PullRequest
0 голосов
/ 15 апреля 2011

Итак, я пытаюсь использовать функции TPL в .NET 4.0, и у меня есть такой код (не смейтесь):

/// <summary>Fetches a thread along with its posts.  Increments the thread viewed counter.</summary>
public Thread ViewThread(int threadId)
{
   // Get the thread along with the posts
   Thread thread = this.Context.Threads.Include(t => t.Posts)
       .FirstOrDefault(t => t.ThreadID == threadId);

   // Increment viewed counter
   thread.NumViews++;
   Task.Factory.StartNew(() =>
   {
       try {
           this.Context.SaveChanges();
       }
       catch (Exception ex) {
           this.Logger.Error("Error viewing thread " + thread.Title, ex);
       }

       this.Logger.DebugFormat(@"Thread ""{0}"" viewed and incremented.", thread.Title);
   });

   return thread;
}

Так что мои непосредственные проблемы с лямбдой таковы.(мой элемент структуры данных сущности), this.Logger (член logger) и thread (используется в вызове logger).Обычно в дни QueueUserWorkItem () я бы подумал, что их нужно будет передать в делегат как часть объекта состояния.Будут ли замыкания спасать меня от необходимости делать это?

Другая проблема состоит в том, что тип, в котором эта подпрограмма реализует IDisposable и, следовательно, находится в операторе using.Так что, если я сделаю что-то вроде ...

using (var bl = new ThreadBL()) {
            t = bl.ViewThread(threadId);
        }

... я собираюсь создать гонку между вызовом dispose () и TPL, использующим мою лямбду?

В настоящее время я вижу, как контекст сохраняет данные обратно в мою базу данных, но без регистрации - без исключений.Это может быть с моей стороны, но что-то в этом коде кажется странным.Я не хочу иметь необработанные исключения в других темах.Любой вход приветствуется!

1 Ответ

0 голосов
/ 31 мая 2011

Что касается вашего вопроса о замыканиях, да, это именно то, о чем замыкания.Вы не беспокоитесь о передаче состояния, вместо этого оно захватывается для вас из любого внешнего контекста и копируется в предоставленный компилятором класс, в котором также будет определен метод closure.Компилятор делает много магии, чтобы сделать вашу жизнь проще.Если вы хотите понять больше, я настоятельно рекомендую взять C # Джона Скита в глубине.Глава о замыканиях на самом деле доступна здесь .

Что касается вашей конкретной реализации, она не будет работать в основном для той проблемы, которую вы упомянули: задача будет запланирована в конце ViewThread, но потенциально не может быть выполнен до удаления вашего экземпляра ThreadBL.

...