2012-07-15 12 views
5

मैं नियंत्रक विधि के भीतर से एक एसिंक्रोनस विधि कैसे निष्पादित कर सकता हूं और एटीएनसीटी प्रतिनिधि के समय से पहले निष्पादन को समाप्त करने के बिना एक HttpStatusCodeResult (200) वापस कर सकता हूं?मैं एएसपीनेट एमवीसी में एसिंक विधि को सही तरीके से निष्पादित कैसे करूं?

मैं एएसपीनेट एप्लिकेशन पर काम कर रहा हूं और मेरी कार्रवाई में से एक मेरे घर नियंत्रक को चलाने के लिए लंबा समय लगता है (10-30 सेकंड)। मैं एक HttpStatusCodeResult (200) वापस करना चाहता हूं और अपना काम चलाना जारी रखता हूं। Functoin को कुछ भी वापस करने की आवश्यकता नहीं है, लेकिन फिर भी यह वास्तव में आग का मामला नहीं है और भूल जाता है क्योंकि मैं तुरंत HttpStatusCodeResult के साथ सर्वर पर प्रतिक्रिया देता हूं।

मैंने प्रतिनिधियों का उपयोग करने की कोशिश की, लेकिन ऐसा लगता है कि एक बार जब मैं कार्रवाई से स्टेटस कोड वापस कर देता हूं, तो प्रतिनिधि निष्पादित करना बंद कर देता है। एक और विकल्प विंडोज़ सेवा बनाना है, लेकिन यह एक फ्लाई को मारने के लिए एक बाजुका का उपयोग करना होगा। मुझे बहुत कम अनुरोध मिलते हैं इसलिए संसाधन और प्रदर्शन मेरे मामले में कोई मुद्दा नहीं है। मैंने सुना है ThreadPool.QueueUserWorkItem एक विकल्प है, लेकिन जो मेरे मामले के लिए सबसे उपयुक्त है?

+0

यह आपकी सबसे अच्छी शर्त हो सकती है: [एएसपी.नेट एमवीसी में एक असीमित नियंत्रक का उपयोग करना] (http://msdn.microsoft.com/en-us/library/ee728598.aspx) –

+0

लेकिन मुझे लगता है कि यह केवल उपयोग को अनुकूलित करता है थ्रेड पूल का, मेरा मतलब है कि मैं httpstatus कोड वापस नहीं कर सकता और निष्पादन जारी रख सकता हूं, _Converting सिंक्रोनस एक्शन विधियों को असीमित क्रिया विधियों_ अनुभाग –

उत्तर

1

एक स्थिर वर्ग बनाएं जो इस लंबे समय तक चलने वाले संचालन का प्रबंधन करता है। यह वर्ग कार्य करने के लिए धागे बनाने के लिए ज़िम्मेदार होगा और किसी भी चल रहे संचालन की स्थिति की जांच करने का एक तरीका भी प्रदान करेगा (यानी यदि यह अभी भी प्रगति पर है या समाप्त हो गया है, और यदि हां, तो परिणाम क्या है)।

आपकी एमवीसी नियंत्रक विधि तब काम करने और उपयोगकर्ता को पूर्ण स्थिति की जानकारी या वर्तमान स्थिति डेटा करने के लिए इस कक्षा का उपयोग करती है।

कुछ इस तरह:

public ActionResult GetSomething(String id) { 
    TaskResult result = TaskClass.GetStatus(id); 
    if(result == null) { // the task has not been run, so start it up 
     TaskClass.StartNew(id); 
     return new View("PleaseWait"); 
    } else if(!result.IsFinished) { 
     return new View("PleaseWait"); 
    } else { 
     return View("Results", result); 
    } 
} 

public static class TaskClass { 
    private static Dictionary<String,TaskResult> _tasks; 
    public static TaskResult GetStatus(String id) { 
     // TODO: Make this code thread-safe 
     if(_tasks.ContainsKey(id)) return _tasks[id]; 
     return null; 
    } 
    public static void Start(String id) { 
     _tasks.Add(id, new TaskResult("Working")); 
     Thread thread = new Thread(SomeExpensiveOperation); 
     thread.Start(id); 
    } 
} 

SomeExpensiveOperation के अंत में कोड के रूप में समाप्त हो गया है कि TaskResult के निशान होगा।

+0

पर जांचें ऐसा लगता है जैसे यह काम कर सकता है। एकमात्र भाग जिसे मैं काफी समझ नहीं सकता हूं: * कंट्रोलर विधि निष्पादित करने के बाद भी एसिंक परिणाम के लिए कौन सुन रहा है? * –

+0

कोई नहीं। श्रोता होने की आवश्यकता नहीं है। ग्राहक द्वारा अनुरोध किए जाने तक पूरा ऑपरेशन इन-मेमोरी के परिणामों को बस स्टोर करें। उदाहरण के लिए मेरा अद्यतन उत्तर देखें। इस मामले में मैं एक शब्दकोश का उपयोग करता हूं (ध्यान दें कि मेरा कोड थ्रेड सुरक्षित नहीं है और बग के साथ झुका हुआ है, लेकिन आपको सामान्य विचार प्राप्त करने में सक्षम होना चाहिए)। – Dai

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