2016-04-10 25 views
1

içinde kesme noktası kullanmadığı sürece boş koleksiyona geri dönüyor C# içinde bir program yazıyor, diğer programlardan gelen iletileri alıp mesajları okumak ve bazı durumlarda yanıtları hazırlayıp göndermek gerekiyor. Tek bir iletiyi işlemek için bu yöntemi yazdım ve eşzamansız olarak (await kullanarak) veya türüne bağlı olarak eşzamanlı olarak adlandırıyorum.Beklenen yöntem,

public async void HandleMessage(Message message) 
{ 
    IEnumerable<Tuple<Message, ulong>> responses; 
    try 
    { 
     if (!_communicateTypesToHandleSync.Contains(message.GetType())) 
     { 
      responses = await Task.Run(() => _requestHandler.HandleRequest(message)); 
     } 
     else 
     { 
      responses = _requestHandler.HandleRequest(message); 
     } 
     foreach (var response in responses) 
     { 
      CSMessageHandler.AddMessageToSend(response.Item1, response.Item2); 
     } 
    } 
    catch (Exception ex) 
    { 
     _logger.Error(ex, "Error while handling message"); 
    } 
} 

sorun bekliyor kullanılarak HandleRequest arayarak hep (bir koşullu kesme ile işaretli) boş bir koleksiyon dönmek gibi görünüyor olmasıdır. Hata ayıklamaya çalıştım ve sonunda ne olup bittiğini öğrendiğimde, yalnızca koleksiyon boş değilse duracak olan HandleRequest'un sonunda bir kesme noktası belirledim. Bu kesme noktası kod yürütme üzerinde durdu ve HandleMessage içinde bile HandleRequest'dan çıktığında responses boş bırakmadım.

+0

Senkron bir yöntem beklemek kötü bir kod uygulamasıdır; Ayrıca bu bağlamda Task.Run kullanmayı bırakın. [Bu] (https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Async-Library-Methods-Shouldn-t-Lie) mükemmel videoya bakın. –

+0

@JeroenHeier bunu birkaç cümlede özetleyelim. 16 dakika benim için çok uzun ... – Eser

+0

Bu hiç mantıklı değil. Bu ne tür bir uygulama? Arama kodu nedir? –

cevap

2

HandleMessage bir Task geçersiz veya eğer Task<IEnumerable<Tuple<Message, ulong>>> Eğer IEnumerable<Tuple<Message, ulong>> dönmek istiyorum eğer dönmelidir ya. Bir delege olmadıkça void kullanmamalısınız. Eğer HandleMessagebir çağrı yaparken

Kodunuz, yöntem, bir boşluk olduğundan

public async Task<IEnumerable<Tuple<Message, ulong>>> HandleMessage(Message message) 
{ 
    IEnumerable<Tuple<Message, ulong>> responses; 
    try 
    { 
     if (!_communicateTypesToHandleSync.Contains(message.GetType())) 
     { 
      responses = await Task.Run(() => _requestHandler.HandleRequest(message)); 
     } 
     else 
     { 
      responses = _requestHandler.HandleRequest(message); 
     } 
     foreach (var response in responses) 
     { 
      CSMessageHandler.AddMessageToSend(response.Item1, response.Item2); 
     } 

     return responses; 
    } 
    catch (Exception ex) 
    { 
     _logger.Error(ex, "Error while handling message"); 
    } 
} 

Çağrı

await HandleMessage(Message message); 

olmalıdır olmalı, bu beklenen varlık değildir. Yöntem 1 iş parçacığı üzerinde girilir, sonra başka bir iş parçacığı başlatmak için bir Task.Run yaparsınız. İkinci bir iş parçacığı başlatıldığında, iş parçacığı 1 serbest bırakılır ve bir çağrı işlevi üzerinde çalışmaya devam eder. Örneğin

:

//do one thing 
HandleMessage(message); 
//Do other work 

Task.Run başka iş parçacığı yukarı spin zaman serbest bırakıldığında 1 diğer işleri yapmaya devam ediyorum iplik.