2015-01-26 2 views
-1

У меня есть asked a question о том, как узнать, когда строка кода другой другой библиотеки библиотеки изменяется в моем коде. Я могу получить доступ к самой строке в любое время. но не может реализовать INotifyPropertyChanged, так как это не мой код.Как заменить (async) BackgroundWorker с (async) Task.Run (из TPL)?

Мне предложили использовать BackgroundWorker, и это решение действительно работает для меня! , но я старался убедиться, что это лучшее решение, и получил совет, чтобы посмотреть на TPL. Дальнейшие исследования показали, что Task.Run of TPL может быть лучшим решением, как упоминалось здесь, например: Task parallel library replacement for BackgroundWorker?, но я не мог реализовать его в коде.

Я пытаюсь заменить этот код на Task.Run (Спасибо @ a.azemia)

 BackgroundWorker bw = new BackgroundWorker(); 
    bw.DoWork += (s, e) => 
     { 
      while (true) 
      { 
       if (!fc.SecondString.Equals(AnotherPartyLibrary.firstString)) 
       { 
        fc.SecondString = AnotherPartyLibrary.firstString; 
       } 
       Thread.Sleep(1000); 
      } 
     }; 
    bw.RunWorkerAsync(); 

я не мог найти ни одного примера, который подходит моему сценарию и пытался узнать из других примеров с не успех. Мне нужна петля while внутри задачи, и ей нужно запустить asynchronously, как и BackgroundWorker. не смог найти какой-либо пример с циклом while в задаче, поэтому я не уверен, как это можно сделать.

Я также читал, что выражения Лямбда используют больше ресурсов, и это было показано в каком-то тесте, которое я видел, поэтому мне хотелось бы избежать Лямбды, если это возможно.

Спасибо за помощь!

+0

Что касается вниз голосов, что случилось с моим вопросом? Я просто хотел бы упомянуть, что я провел много часов (!!), пытаясь заставить его работать. Я не прошу сэкономить свое время, но потому, что я действительно пробовал все, что мог, и я действительно застрял. – Ray

+0

Для вашего простого сценария я не вижу никакой пользы в изменении. Это можно было бы сделать только с помощью таймера ... –

+1

Избегание выражения lamda из-за некоторых накладных расходов на ресурсы - это улучшение микропроизводительности. Игнорируйте его и просто используйте lamdas – Sievajet

ответ

2

Попробуйте это (непроверенные):

public async Task DoWork() 
{ 
    while (true) 
    { 
     if (!fc.SecondString.Equals(AnotherPartyLibrary.firstString)) 
     { 
     fc.SecondString = AnotherPartyLibrary.firstString; 
     } 

     await Task.Delay(1000); 
    }  
}  

Я использовал Task.Delay вместо Thread.Sleep как бывший не блокирует поток в то время как задержка происходит. Вы можете вызвать эту функцию с await

await DoWork(); 
+0

Спасибо за ваш ответ @Ned Stoyanov, я не смог его построить, если я запустил DoWork(); код в методе Form_Load, ошибка VS говорит: оператор «ожидание» может использоваться только в асинхронном методе.Подумайте о маркировке этого метода с помощью модификатора «async» и измените его тип возврата на «Задача». Я, наверное, что-то не так понимаю, я .. Еще раз спасибо. – Ray

+0

Метод, который вы вызываете из него, должен быть 'async' и в идеале возвращать' Task' или 'Task '. Это имеет тенденцию иметь эффект цепной реакции в вашем коде, и вам может потребоваться отметить несколько методов как «async» –

+0

Спасибо @Ned Stoyanov, извините за все мои вопросы, я новичок во всем этом параллельном программировании .. так что, если я хотите вызвать этот метод DoWork из метода Form_Load? Может/должен ли я сделать это async? – Ray

0

Я до сих пор не вижу никакой реальной пользы, но здесь вы идете:

private Task T; 

    private void Form1_Load(object sender, EventArgs e) 
    { 

     // ... make sure your string stuff is setup first ... 

     T = Task.Run(delegate() { 
      while (true) 
      { 
       // ... code ... 
       System.Threading.Thread.Sleep(1000); 
      } 
     }); 
    }  
+0

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

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