SORU
13 EYLÜL 2012, PERŞEMBE


Zaman uyumsuz/vs BackgroundWorker bekliyor

Son birkaç gün içinde yeni özelliklerini test ettik .net 4.5 ve c# 5.

Yeni zaman uyumsuz/bekliyor özelliklerini seviyorum. Daha önce BackgroundWorker hassas kullanıcı arayüzü ile arka planda uzun işlemler işlemek için kullanılan vardı.

Benim sorum: bu yeni ve güzel özelliklere sahip sonra, zaman/bekliyor ve 43 ** zaman zaman uyumsuz kullanmalıyım? Her ikisi için de ortak senaryolar nelerdir?

CEVAP
13 EYLÜL 2012, PERŞEMBE


Bu büyük olasılıkla TL;birçokları için, ancak, BackgroundWorker await bu karşılaştırma elma ve portakal ve düşüncelerimi karşılaştırmak gibi bence DR izleyin:

BackgroundWorker iş parçacığı havuzu iş parçacığı üzerinde arka planda gerçekleştirmek, yapmak istediğiniz tek bir görev modeli içindir. async/await uyumsuz uyumsuz işlemler üzerinde bekleyen bir sözdizimi. Bu işlem olabilir veya bir iş parçacığı havuzu iş parçacığı veya bile kullanamazlarbaşka bir iş parçacığı. Yani elma ile armut gibiler.

Örneğin, await ile aşağıdaki gibi bir şey yapabilirsiniz:

using (WebResponse response = await webReq.GetResponseAsync())
{
    using (Stream responseStream = response.GetResponseStream())
    {
        int bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length);
    }
}

Ama, muhtemelen, daha önce bir arka plan worker (işçi, büyük olasılıkla böyle bir şey yapacağını model .NET 4.0 (await önce):

webReq.BeginGetResponse(ar =>
{
    WebResponse response = webReq.EndGetResponse(ar);
    Stream responseStream = response.GetResponseStream();
    responseStream.BeginRead(buffer, 0, buffer.Length, ar2 =>
    {
        int bytesRead = responseStream.EndRead(ar2);
        responseStream.Dispose();
        ((IDisposable) response).Dispose();
    }, null);
}, null);

Elinde disjointness 17*/await*olmadan using kullanamazsınız nasıl iki sözdizimi arasında karşılaştırıldı ve fark.

Ama, BackgroundWorker ile böyle bir şey yapmazsın. BackgroundWorker genellikle modelleme için UI yanıt etkisi istemediğiniz uzun süren tek kişilik bir operasyon. Örneğin:

worker.DoWork  = (sender, e) =>
                    {
                    int i = 0;
                    // simulate lengthy operation
                    Stopwatch sw = Stopwatch.StartNew();
                    while (sw.Elapsed.TotalSeconds < 1)
                          i;
                    };
worker.RunWorkerCompleted  = (sender, eventArgs) =>
                                {
                                    // TODO: do something on the UI thread, like
                                    // update status or display "result"
                                };
worker.RunWorkerAsync();

Gerçekten uyumsuz, BackgroundWorker ile bekliyor/kullanabilirsiniz orada sizin için iş parçacığı oluşturma Bir şey yok.

Şimdi, VUK yerine kullanabilirsiniz:

var synchronizationContext = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() =>
                      {
                        int i = 0;
                        // simulate lengthy operation
                        Stopwatch sw = Stopwatch.StartNew();
                        while (sw.Elapsed.TotalSeconds < 1)
                              i;
                      }).ContinueWith(t=>
                                      {
                                        // TODO: do something on the UI thread, like
                                        // update status or display "result"
                                      }, synchronizationContext);

Bu durumda TaskScheduler şayet (25* *varsayılan varsayarak) oluşturuyor, ve şöyle: await kullanabilirsiniz

await Task.Factory.StartNew(() =>
                  {
                    int i = 0;
                    // simulate lengthy operation
                    Stopwatch sw = Stopwatch.StartNew();
                    while (sw.Elapsed.TotalSeconds < 1)
                          i;
                  });
// TODO: do something on the UI thread, like
// update status or display "result"

Benim görüşüme göre, büyük bir karşılaştırma ilerleme raporlama olsanız da, olmasanız da. Örneğin, BackgroundWorker like bu olabilir:

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged  = (sender, eventArgs) =>
                            {
                            // TODO: something with progress, like update progress bar

                            };
worker.DoWork  = (sender, e) =>
                 {
                    int i = 0;
                    // simulate lengthy operation
                    Stopwatch sw = Stopwatch.StartNew();
                    while (sw.Elapsed.TotalSeconds < 1)
                    {
                        if ((sw.Elapsed.TotalMilliseconds0) == 0)
                            ((BackgroundWorker)sender).ReportProgress((int) (1000 / sw.ElapsedMilliseconds));
                          i;
                    }
                 };
worker.RunWorkerCompleted  = (sender, eventArgs) =>
                                {
                                    // do something on the UI thread, like
                                    // update status or display "result"
                                };
worker.RunWorkerAsync();

Ama, olmaz anlaşma ile bazı bu çünkü edersin sürükle ve bırak arka planda çalışan bileşeni için tasarım yüzeyi şeklinde bir şey olabilir mi?async/await ve Task... yani olmayacak el ile oluşturmak nesne, set özelliklerini ayarlayın ve olay işleyicileri. sadece*,* 34*,* 33 ProgressChanged olay işleyicileri vücut doldurun.

Eğer "zaman uyumsuz/beklemek, gibi bir şey yapmak istiyorum:." dönüştürülürse

     var progress = new Progress<int>();

     progress.ProgressChanged  = ( s, e ) =>
        {
           // TODO: do something with e.ProgressPercentage
           // like update progress bar
        };

     await Task.Factory.StartNew(() =>
                  {
                    int i = 0;
                    // simulate lengthy operation
                    Stopwatch sw = Stopwatch.StartNew();
                    while (sw.Elapsed.TotalSeconds < 1)
                    {
                        if ((sw.Elapsed.TotalMilliseconds0) == 0)
                        {
                            progress.OnReport((int) (1000 / sw.ElapsedMilliseconds))
                        }
                          i;
                    }
                  });
// TODO: do something on the UI thread, like
// update status or display "result"

Tasarımcı bir yüzey üzerinde bir bileşen sürükleyin yeteneği olmadan, gerçekten okuyucu için karar vermeye gerek yok "". daha iyi Ama, bu, bana, await ve yerleşik Stream.ReadAsync gibi yöntemler sizi bekliyor olabilir olup olmadığını BackgroundWorker, arasında karşılaştırma. örneğin eğer amaçlandığı gibi BackgroundWorker kullanıyorsanız, dönüştürmek sabit await kullanmak için olabilir.

Diğer düşünceler: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Alfredo Garcia

    Alfredo Garc

    25 Mayıs 2007
  • My name is Festis and I'm free

    My name is F

    2 EKİM 2011
  • nigahiga

    nigahiga

    21 Temmuz 2006