2012-04-09 29 views
16

Gerçekten maksimum potansiyeline TplDataflow kullanmıyorum ... http://social.msdn.microsoft.com/Forums/en-US/tpldataflow/thread/89b3f71d-3777-4fad-9c11-50d8dc81a4a9Görünür BufferBlock.Post/Receive/ReceiveAsync ırk/böcek

Bilmem karşılıklı yayınlandı. ATM BufferBlock'u, üreticinin ve tüketicinin farklı oranlarda çalıştığı mesaj geçişi için güvenli bir kuyruk olarak kullanıyorum. 'un nasıl devam edeceğine dair beni tuhaf bırakan garip davranışlar görüyorum. (2000 hattı dağıtılmış çözeltinin bir parçası olan), yukarıdaki kod

private BufferBlock<object> messageQueue = new BufferBlock<object>(); 

public void Send(object message) 
{ 
    var accepted=messageQueue.Post(message); 
    logger.Info("Send message was called qlen = {0} accepted={1}", 
    messageQueue.Count,accepted); 
} 

public async Task<object> GetMessageAsync() 
{ 
    try 
    { 
     var m = await messageQueue.ReceiveAsync(TimeSpan.FromSeconds(30)); 
     //despite messageQueue.Count>0 next line 
     //occasionally does not execute 
     logger.Info("message received"); 
     //....... 
    } 
    catch(TimeoutException) 
    { 
     //do something 
    } 
} 

, Send periyodik olarak her 100ms veya sözde edilmektedir. Bu, öğenin saniyede 10 defa Post ve messageQueue arasında olduğu anlamına gelir. Bu doğrulandı. Ancak, zaman zaman ReceiveAsync'un zaman aşımı içinde tamamlanmadığı (yani Post'un ReceiveAsync'un neden olmamasına neden olduğu) ve TimeoutException'un 30'lardan sonra yükseltildiği anlaşılmaktadır. Bu noktada, messageQueue.Count yüzlerce. Bu beklenmedik bir şey. Bu sorun da (1 post/second) daha yavaş gönderme oranlarında gözlemlenmiştir ve genellikle 1000 ürün BufferBlock içinden geçmeden önce gerçekleşir.

Yani, bu soruna, ben çalışır aşağıdaki kodu, kullanıyorum çalışmak, ancak

public async Task<object> GetMessageAsync() 
    { 
     try 
     { 
      object m; 
      var attempts = 0; 
      for (; ;) 
      { 
       try 
       { 
        m = await messageQueue.ReceiveAsync(TimeSpan.FromSeconds(1)); 
       } 
       catch (TimeoutException) 
       { 
        attempts++; 
        if (attempts >= 30) throw; 
        continue; 
       } 
       break; 

      } 

      logger.Info("message received"); 
      //....... 
     } 
     catch(TimeoutException) 
     { 
      //do something 
     } 
    } 

Bu bir yarış durumu benziyor (nedeniyle meydana gelen yukarıdaki hatadan) alırken bazen 1s gecikme nedenleri Bana TDF içinde, ama ben benzer bir şekilde BufferBlock kullandığım diğer yerlerde bu neden olmasın altını alamıyorum. Deneysel olarak ReceiveAsync ile Receive arasında değişiklik yapmanıza yardımcı olmuyor. Kontrol etmedim, ama izolasyonda hayal ediyorum, yukarıdaki kod mükemmel çalışıyor. "TPL Dataflow'a Giriş" bölümünde (tpldataflow.docx) belgelenmiş bir model.

Bunun dibine ulaşmak için ne yapabilirim? Ne olduğunu anlamaya yardımcı olabilecek herhangi bir metrik var mı? Güvenilir bir test durumu oluşturamazsam, daha fazla bilgiyi nasıl sunabilirim?

Yardım!

+1

Ne yaptığınızı veya beklentilerinizi burada yanlış bir şey göremiyorum. Kesinlikle bu etkinliğin MSDN forumlarından daha fazla tutulması gerektiğini düşünüyorum. Şimdiden @StephenToub'un dikkatini çektin ve kesinlikle ona bakmak istediğiniz adam. –

+0

Hayır. Asla dibe vurmadım. Sorunu küçük, kendi kendine yeten bir örnekte yeniden üretemedim. Ben sadece BufferBlock kullanıyordum, bunun yerine kendi async sıra uygulamasını yaptım. Başka bir kodu değiştirmem gerekmedi ... Ben sadece kullandığım BufferBlock arabiriminin parçalarını yeniden oluşturdum. Şimdi bir muamele çalışıyor, bu da bana bir şeyler olduğunu düşünmeme neden oluyor, ama bunu kanıtlayamıyorum. Grr. – spender

+0

@spendor Çok ilginç, garip bir şekilde BufferBlock'u bulduktan sonra kendi asenkron eşzamanlı kuyruğumu ...şimdi yeniden düşünmek zorundayım. Teşekkürler. –

cevap

1

Stephen Aşağıdaki solüsyon olduğunu düşünüyorum görünmektedir

var m = messageQueue.ReceiveAsync() beklemektedir;

yerine:

var m = bekliyor messageQueue.ReceiveAsync (TimeSpan.FromSeconds (30));

Bunu onaylayabilir veya reddedebilir misiniz?

+0

Bu işe yaramadı. Hangi ReceiveAsync aşırı yüklenmesini seçmedim, sonuç aynıydı. Çözümüüm için yukarıdaki yorumuma bakın. – spender