2011-09-03 8 views
9

में कहा जाने वाला विनाशक कब होता है मुझे एक सेवा बनाने की आवश्यकता होती है जो डब्ल्यूसीएफ सत्र बनाए रखेगी। कन्स्ट्रक्टर में मैंने डीबी से डेटा में पढ़ा और जब सत्र समाप्त होता है तो मुझे इसे वापस सहेजना पड़ता है।डब्लूसीएफ सेवा

यदि मैं क्लाइंट पर बंद() को कॉल करता हूं तो सत्र सही होता है (मेरा क्लाइंट सेवा क्लाइंट SvcUtil.exe के साथ बनाया गया था)।

जब मैं इसका परीक्षण करता हूं तो मुझे लगता है कि इसे कभी-कभी लगभग बाद में बुलाया जाता है। 10 मिनट, कभी-कभी 20 मिनट के बाद और कभी-कभी बिल्कुल नहीं।

तो विनाशक कहलाता है कब?

सेवा

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
    public class Service:IService 
    { 
    private User m_User = null; 

    public Service() 
    { 
     m_User = User.LoadFromDB(); 
    } 

    ~Service() 
    { 
     m_User.SaveToDB(); 
    } 

    public void SetName(string p_Name) 
    { 
     m_User.Name = p_Name; 
    } 
    } 

Web.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <sessionState timeout="2" /> 
    </system.web> 
    <system.serviceModel> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
     <services> 
     <service name="Karatasi.Services.B2C" behaviorConfiguration="ServiceBehavior"> 
      <host> 
      <baseAddresses> 
       <add baseAddress="http://localhost:19401/B2C.svc"/> 
      </baseAddresses> 
      </host> 
     <endpoint 
      address="" 
      binding="wsHttpBinding" 
      bindingConfiguration="test" 
      contract="Karatasi.Services.IB2C" 
     /> 
     <endpoint 
      address="mex" 
      binding="mexHttpBinding" 
      contract="IMetadataExchange" 
     /> 
     </service> 
    </services> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="test" receiveTimeout="00:01:00" > 
     <reliableSession enabled="true" ordered="false" inactivityTimeout="00:01:00"/> 
     </binding> 
    </wsHttpBinding> 
    </bindings> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior name="ServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="false" /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 
</configuration> 

ग्राहक

ServiceClient serviceClient = null; 
    try 
    { 
     serviceClient = new ServiceClient(); 
     serviceClient.SetName("NewName"); 
     Console.WriteLine("Name set"); 
    } 
    catch (Exception p_Exc) 
    { 
     Console.WriteLine(p_Exc.Message); 
    } 
    finally 
    { 
     if (serviceClient != null) 
     { 
     if (serviceClient.State == CommunicationState.Faulted) 
     { 
      serviceClient.Abort(); 
     } 
     else 
     { 
      serviceClient.Close(); 
     } 
     } 
     Console.ReadKey(); 
    } 
+0

का उपयोग कर सकते हैं सबसे पहले यह पूरी तरह से गलत सेवा डिज़ाइन है। –

उत्तर

16

docs

जनसंपर्क से ogrammer पर कोई नियंत्रण नहीं है जब विनाशक को कहा जाता है क्योंकि यह कचरा कलेक्टर द्वारा निर्धारित किया जाता है। कचरा कलेक्टर उन वस्तुओं के लिए जांच करता है जिनका उपयोग अब एप्लिकेशन द्वारा नहीं किया जा रहा है। यदि यह किसी ऑब्जेक्ट को विनाश के योग्य मानता है, तो यह विनाशक (यदि कोई है) को कॉल करता है और ऑब्जेक्ट ऑब्जेक्ट को संग्रहीत करने के लिए उपयोग की जाने वाली मेमोरी को पुनः प्राप्त करता है। जब कार्यक्रम निकलता है तो विनाशकों को भी बुलाया जाता है।

आपके कार्यान्वयन में कोई समस्या है। डेटा को बनाए रखने के लिए आप विनाशक का उपयोग कर रहे हैं। यह गलत है क्योंकि विनाशकों को निश्चित रूप से नहीं कहा जा सकता है, वे एक अलग अंतिमकरण कतार में संसाधित होते हैं। इसका मतलब यह है कि भले ही आपने वस्तु को नष्ट कर दिया हो, फिर भी इसके विनाशक को तुरंत नहीं बुलाया जा सकता है।

ठीक करने के लिए कैसे इस
नाशक निकालें और इसके बजाय IDisposable पैटर्न का उपयोग, निपटान में तर्क को बचाने डाल दिया। एक बार जब सत्र समाप्त हो जाता है, WCF IDisposable.Dispose

public class Service:IService, IDisposable 
{ 
    public void Dispose() 
    { 
     //your save logic here 
    } 
} 

संपादित
Pls भी फोन करेगा यह जवाब देने के लिए टिप्पणी देखें। मैं वास्तव में सहमत हूं कि डेटाबेस के लिए IDisposable उचित स्थान नहीं है, इससे पहले मुझे नहीं हुआ था। इसके अलावा टिप्पणी में दिए गए समाधानों के लिए आप explicit session demarcation

+16

नहीं! इसे 'पहचानने योग्य' में मत डालें। या तो! 'IDISposable.Dispose 'प्रबंधित संसाधनों की सफाई के लिए है। डेटाबेस में सहेजना एक प्रबंधित संसाधन की सफाई नहीं कर रहा है। यह इस इंटरफेस के * स्वीकृत * और * अपेक्षित * उपयोग के खिलाफ चला जाता है। या तो 'SetName' डेटाबेस में परिवर्तन करें, या सेवा 'Commit' पर एक और तरीका प्रदान करें। इसके अलावा, मामूली क्विबल, सी # में हम इसे "फाइनेंजर" कहते हैं। हां, भ्रम इस विषय पर बहुत अधिक है। – jason

संबंधित मुद्दे