2016-03-07 15 views
5

Mam problem z oznaczeniem mojej BrokeredMessage jako zakończoną.BrokeredMessage disposed

prosty kod, który działa jak oczekiwano:

private void OnMessageArrived(BrokeredMessage message) 
{ 
    var myObj= message.GetBody<MyObject>(); 

    //do things with myObj 

    message.Complete();    
} 

Kiedy próbuję czekać na użytkownika, aby zakończyć myObj otrzymuję wyjątek:

brokeredmessage został umieszczony

Kod poniżej:

private Dictionary<long, BrokeredMessage> ReceivedMessages;  
ReceivedMessages = new Dictionary<long, BrokeredMessage>(); 

private void OnMessageArrived(BrokeredMessage message) 
{ 
    var myObj= message.GetBody<MyObject>(); 
    ReceivedMessages.Add(myObj.Id, message); 

    //do things with myObj  
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    // get myObj on which user clicked 

    ReceivedMessages[myObj.Id].Complete(); 
    ReceivedMessages.Remove(myObj.Id);   
} 

Dla mnie to wygląda ServiceBus jakoś tracą połączenie z rzeczywistego obiektu w C#

Coś podobnego do wolnostojącego obiektu w EF, tylko w tym przypadku celem jest odłączana od ServiceBus

EDYTOWANIE:

Ważne jest, aby zaznaczyć wiadomość jako kompletną dopiero po kliknięciu przycisku użytkownika. W przypadku awarii AC (lub podobnych rzeczy) chcę, aby wiadomości nadal pozostały na Temacie usługi magistrali, aby przy następnym uruchomieniu aplikacji użytkownik ponownie otrzymywał wiadomości, których nie przetworzył.

Odpowiedz

2

Nie należy przechowywać samej wiadomości z brokerem. Po wywołaniu metody .Complete(), to jest to, co dzieje się according to the documentation:

zakończeniu operacji odbioru komunikatu i wskazuje, że wiadomość powinna zostać oznaczona jako przetworzone i usunięte

Co należy zrobić, zamiast jest przechowywanie MyObject typów obiektów w słowniku, ponieważ wyrzucone wiadomości zostaną zniszczone po zakończeniu.

private Dictionary<long, MyObject> ReceivedMessages;  
ReceivedMessages = new Dictionary<long, MyObject>(); 

I w odpowiednim kawałku kodu:

var myObj= message.GetBody<MyObject>(); 
ReceivedMessages.Add(myObj.Id, myObj); 
+0

Czy mogliby Państwo polecić rozwiązanie tego problemu: a następnie: 1. Otrzymana wiadomość, jej dane podzielone na części i przesłane do przetwarzania asynchronicznego. Chcemy zablokować wiadomość, dopóki jej dane nie zostaną przetworzone przez użytkownika, który ją nabył. 2. Jeśli wystąpi wyjątek lub użytkownik opuści program, odblokuj wiadomość, aby inny użytkownik mógł ją przetworzyć później. 3. Jeśli/kiedy przetwarzany jest ostatni fragment danych, usuń wiadomość z ServiceBus, ponieważ jej dane zostały poprawnie przetworzone. – ErroneousFatality

+0

Tak. Przestań wywoływać funkcję Complete() w wiadomości, dopóki nie skończysz. –

+0

Przepraszam, jeśli się mylę, ale właśnie to robi OP. Zapisuje wiadomość w słowniku, aby mógł wywołać polecenie Complete po zakończeniu przetwarzania asynchronicznego. Zalecamy, aby zamiast tego zrobić to i zapisać tylko dane, które przetwarza. Jak nazwałby to "Complete" wiadomością po procesie asynchronicznym? – ErroneousFatality

0

Spójrz na ServiceBus LockToken.

Można zadzwonić Complete (lockToken)

+0

Jeszcze ten sam wyjątek _brokeredmessage został usunięty_ – topolm

2

Jest to bardzo niejawny i nie stwierdzono również w dokumentacji, o ile mi wiadomo, ale kiedy zapisać się do SB Wątek/Abonament można uzyskać dostęp tylko obiekt BrokeredMessage w zakresie wykonawczym delegata oddzwaniania OnMessage dostarczasz do SubscriptionClient.OnMessage.

Po powrocie wywołania, BrokeredMessage jest usuwany.

Jeśli chcesz buforować wiadomość i oznaczyć ją jako kompletny/opuszczony/deadletter należy buforować BrokeredMessage.LockToken wraz z innej własności trzeba jak treść wiadomości, a następnie za pomocą

  • SubscriptionClient.Complete
  • SubscriptionClient.Abandon
  • SubscriptionClient.Deadletter

które otrzymują LockToken jako parametr, jeśli chcesz oznaczyć je jako kompletne.

Powiązane problemy