2013-01-18 14 views
10

Kendinden barındırılan bir wcf dupleks geri arama hizmeti ile ilgili bir sorunum var. Ben mesajı içeren bir InvalidOperationException olsun: Mevcut mesaj işleme tamamlanıncaya kadar cevap alınamaz çünküWCF dupleks geri arama servisi ile kilitlenme sorununu önleme

Bu işlem çıkmaza sokacaktır. sırasız mesaj işlemeye izin vermek istiyorsanız, Reentrant ConcurrencyMode veya CallbackBehaviorAttribute'ta Çoklu seçeneğini belirtin. Ben InvalidOperationException anlıyoruz

public interface ILvssClientCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void SendClientCallback(LvssCallbackMessage callbackMessage); 

    [OperationContract(IsOneWay = false)] 
    List<SpecimenTemplateDescriptor> GetTemplateDescriptorList(DrawerLayout drawerLayout); 

    [OperationContract(IsOneWay = false)] 
    SpecimenTemplate SelectSpecimenTemplate(string templateName, int version); 

    [OperationContract] 
    void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol, 
    int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError); 

    [OperationContract] 
    void LvssRobotStatusChange(LVSSStatus status); 
} 

: Burada

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IClientCallback))] 

[ServiceContract] 
public interface IClientToService 
{ 
    [OperationContract(IsOneWay = false)] 
    LVSSStatus GetLvssStatus(); 

    [OperationContract(IsOneWay = true)] 
    void PickSpecimen(long trackingNumber, int destCode); 

    [OperationContract(IsOneWay = true)] 
    void CancelCurrentPickTransaction(); 
} 

benim geri arama arayüzü: Burada
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = true)] 

benim hizmet sözleşmesidir: Burada

benim hizmet davranıştır bir geri çağırma operasyonu ne zaman neden olur İstemcide açık, geçerli bir işlemin işlenmesi için servis zaten kilitlendi. Yani, bir kilitlenme oluşur. false

Birden benim ConcurrencyMode değişen denedim

ve UseSynchronizationContext.

Birincisi:

Hala hizmetiyle iki sorun bkz GetLvssStatus() (hızla UI butonuna tıklayarak) hızla çağrıldığında aşağıdaki hizmet operasyonu uygulaması WPF Müvekkilime donduruyor. Bu yöntem tek bir yol değildir ve hizmetten istemciye senkronize olarak numaralandırılmış bir tür döndürür.

[OperationContract(IsOneWay = false)] 
    LVSSStatus GetLvssStatus(); 

* Ne bu durumda dondurmak için benim wpf uygulaması neden olur? * Uygulamanın donmasını önlemek için ne yapabilirim? Eşzamansız çağrı olarak backgroundworker iş parçacığı kullanırsam, uygulama donmaz. Eşzamanlı çalışmak için bu yönteme gerçekten ihtiyacım var.

İkincisi: Ben IsOneWay = true için geri çağırma yöntemi LvssRobotStatusChange atadığınızda, ben bir ObjectDisposedException olsun: bırakılmış nesneye erişilemiyor. Nesne adı: 'System.ServiceModel.Channels.ServiceChannel'.

[OperationContract(IsOneWay = true)] 
    void LvssRobotStatusChange(LVSSStatus status); 

* Ya bu ObjectDisposedException neden olur? * Bu durumda IsOneWay atamasını atlamak doğru mudur? Bu durumda IsOneWay'i kullanmak, geri aramanın herhangi bir istisna olmadan tamamlanmasını sağlar.

* Bu sorunlar parçacığı güvenli kod eksikliğinden kaynaklanan olabilir mi?
*
Öyleyse, bir ConcurrencyMode.Multiple hizmet davranışı iş parçacığı güvenli hale getirmek için en iyi uygulama nedir?

Bu sorularla ilgili herhangi bir yardım çok takdir edilmektedir.

* İLK DÜZENLEME Dubleks kanalımın oluşturulmasıyla ilgili biraz daha fazla bilgi. Wpf görünüm modelim, kanalımın oluşturulmasını ele almaktan sorumlu bir proxy nesnesi oluşturur. Kanalımı müşteri tarafında yeni bir iş parçacığına ayarlamak için yapılan tüm denemeler, hizmet geri çağırma nesnesini kullanmaya çalıştığında bir ObjectDisposedException ile sonuçlanır.

* İKİNCİ DÜZENLEME ben IsOneWay = true ayarlamak için boşluk yöntemi ile işlem sözleşmeleri alabilirsiniz eğer benim servis çalışması gerektiğini düşünüyoruz. Reentranın eşzamanlı olmasıyla birlikte, ana kanal dişi, bu yöntemlerin herhangi bir kilitlemeye bakılmaksızın geçmesine izin vermelidir. Ben IsOneWay = true yöntem LvssRobotStatuschange operasyon sözleşme ayarladığınızda

public interface ILvssClientCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void SendClientCallback(LvssCallbackMessage callbackMessage); 

    [OperationContract] 
    List<SpecimenTemplateDescriptor> GetTemplateDescriptorList(DrawerLayout drawerLayout); 

    [OperationContract] 
    SpecimenTemplate SelectSpecimenTemplate(string templateName, int version); 

    [OperationContract(IsOneWay = true)] 
    void SpecimenStoredInContainer(string containerID, bool isValidRackID, int rackRow, int rackCol, int deckRow, int deckCol, 
    int drawerRow, int drawerCol, long trackingNumber, RobotErrors robotError); 

    [OperationContract(IsOneWay = true)] 
    void LvssRobotStatusChange(LVSSStatus status); 
} 

, benim önbelleğe geri arama kanalı bir CommunicationObjectAbortedException atar:
İşte benim geri arama arayüzüdür. Bazı nedenlerden dolayı geri çağırma özelliğim iptal ediliyor.

*** Ne bir geri arama kanalı durduruldu hale gelmesine neden olabilir? Bunu daha önce hiç çalıştırmış olduğunuz

+0

(hizmet veya geri arama arayüzü) barındırma uygulama nedir? –

+0

Uygulamam, geri arama arabirimini barındırıyor. Wpf görünüm modelimden, proxy ve duplex kanalının oluşturulmasından sorumlu bir proxy sınıfı oluşturuyorum. Ardından dupleks kanalı oluşturmak için o sınıftaki Connect() öğesini ararım. Vekil sınıfı, müşterim için geri arama arabiriminin uygulanmasından sorumludur. Senaryomda her zaman bir servis ve bir müşteri olacak. – EnLaCucha

cevap

11

, this link uygulamalar ana iş parçacığı dışında başka bir iş parçacığı üzerinde kanallar oluşturarak tartışır, hangi yardımcı olmalıdır. Karşılaştığım

+1

Harika bağlantı, teşekkürler! Benim durumumda, wpf görünüm modelinde dubleks kanal oluşturmuyorum. Kanal, bir yardımcı proxy sınıfında oluşturulur. Bu sınıfta yeni bir konu oluşturmayı denediğimde, kanal bir nedenle boş kalır. Yukarıda bir numarayı düzenlemeye bakın. – EnLaCucha

+0

Cevabınızı, siz GUI'nin kilitlenmesini önlemek için yeni bir iş parçacığının nasıl tetikleneceğini anlamamda yardımcı olduğum için işaretledim. Uygulamayı tıkayan, tüm dubleks kanalı değil, benim yöntemim için yeni bir konu açtım. Ayrıca benim InCopyOperationExceptions neden oldu benim ServiceContract bazı geçersiz yöntemleri bazı IsOneWay atamaları eksikti. Yani, benim InstanceContextMode.Single ve UseSynchronizationContext = true ile eşzamanlılık bir eşzamanlılık modu kullanımı gayet iyi çalışıyor. ServiceContract'ınızda her zaman eksik olan IsOneWay ödevlerine dikkat edin! – EnLaCucha

5

Sorun:

CallBackHandlingMethod() 
{ 
    requestToService(); // deadlock message.  
} 

çıkış yolu:

CallBackHandlingMethod() 
{ 
    Task.Factory.StartNew(()=> 
    { 
     requestToService(); 
    }); 
} 
+0

Downvoter neden sağlayabilir? thks. – SAm

+0

Bu benim için çalışıyor, teşekkürler. WPF olayında WCF kullanıyorum event = S – egyware

1

benim geri arama uygulanmasına

[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]

ekleyerek basitçe çözüldü benzer bir sorun vardı.

0
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class ServiceCallbackHandler : IServiceCallback 
{ 
... 
} 
+2

Bu kod ne yapıyor ve sorunu nasıl çözüyor? – JJJ

+0

Bu satırları IServiceCallback'i uygulayan sınıfa ekleyin. Bugün problemimi çözüyor! –

İlgili konular