2012-09-09 40 views
0

我们可以使用BackgroundWorker实现响应式用户界面。这里是例子。BackgroundWorker和异步比较

private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     Thread test = new Thread(new ThreadStart(TestThread)); 
     test.Start(); 
    } 
private void TestThread() 
    { 
     for (int i = 0; i <= 1000000000; i++) 
     { 
      Thread.Sleep(1000); 
      Dispatcher.Invoke(
       new UpdateTextCallback(this.UpdateText), 
       new object[] { i.ToString() } 
      ); 
     } 
    } 
    private void UpdateText(string message) 
    { 
     Tests.Add(message); 
    } 
public delegate void UpdateTextCallback(string message); 
     private ObservableCollection<string> tests = new ObservableCollection<string>(); 

    public ObservableCollection<string> Tests 
    { 
     get { return tests; } 
     set { tests = value; } 
    } 

UI:

<StackPanel> 
    <Button Content="Start Animation" Click="Button_Click" /> 
    <Button Content="Start work" Click="Button_Click_1" /> 
    <Rectangle Name="rec1" Fill="Red" Height="50" Width="50"/> 
    <ListView ItemsSource="{Binding Tests}" ScrollViewer.CanContentScroll="True" /> 
</StackPanel> 

在这里,我可以启动动画,并在同一时间,我可以更新使用BackgroundWorker与调度员的UI。

同样的事情,我可以通过异步像这样实现:

private async void GetTests(ObservableCollection<string> items) 
    { 
     for (int i = 0; i < 20; i++) 
     { 
      var s = await GetTestAsync(i); 
      items.Add(s); 
     } 
    } 



async Task<string> GetTestAsync(int i) 
    { 
     await Task.Delay(2000); 
     return i.ToString() + " Call - " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString(); 
    } 

Q.1是否有使用非同步过的BackgroundWorker的任何优势?

什么情况下我应该决定使用他们中的任何一个,并应避免使用其他。

Q.2我想了解使用WPF中的Async -Await。就像没有它我们不能做的那样,现在我们可以轻松地做到这一点。

请指导。

回答

3

问1在BackgroundWorker上使用异步有什么优势?

当然 - 主要是,代码非常简单得多。在这种特殊情况下,你并没有做任何复杂的事情,但只要你开始协调多个任务,拥有更复杂的控制流(循环等),想要处理错误等,它就会产生巨大的差异。

此外,在这种情况下,它节省了额外的线程 - 在您的第二个调用中,所有都发生在UI线程上。在更实际的例子中,你很可能会等待Web服务调用等,这绝对不需要捆绑额外的线程。

Q.2我想了解使用WPF中的Async -Await。就像没有它我们不能做的那样,现在我们可以轻松地做到这一点。

从理论上讲,您可以使用async做的所有事情都可以在没有它的情况下完成。在实践中,正确高效地编写异步代码的复杂性在于锅炉板的数量是一个巨大的障碍。

异步/的await功能,您可以编写异步代码看起来像同步码,与熟悉的控制流程等。这意味着我们可以把它理解,推理它,只担心固有复杂的是,异步带来,而不是写回调所有偶然的复杂性等

+0

它的梦想成真......乔恩的飞碟回答了我的问题......非常感谢您的时间。用Async编写WPF响应式UI的文章,但没有找到不使用BackgroundWorker的原因。任何提示无需比较即可继续。你是最好的人。你让我的星期天...... –

+1

好吧,选项通常是:1)做事异步,不浪费线程。2)使用另一个线程(不管是否是BackgroundWorker)同步执行工作并浪费线程,*和*必须在每次要更新UI或从其获取输入时重新发送到UI。 –

+0

感谢Jon的建议。现在我知道正确使用异步... –