डब्ल्यूसीएफ के पीछे डब्ल्यूपीएफ सर्वर-पक्ष का उपयोग Office सर्वर-पक्ष चलाने के बराबर नहीं है! पूरी तरह से डब्ल्यूपीएफ कुछ डीएलएल है, और वास्तव में किसी अन्य पुस्तकालय सर्वर-पक्ष का उपयोग करने से अलग नहीं है। यह वर्ड या एक्सेल, जहां यूजर इंटरफेस सहित दृश्य, पीछे एक पूरा आवेदन लोड कर रहे हैं, ऐड-इन्स, पटकथा भाषा, आदि से पूरी तरह से अलग है
मैं के लिए WCF पीछे सर्वर पर WPF उपयोग किया गया है वर्षों। यह एक बहुत ही सुंदर और कुशल समाधान है:
DirectX सॉफ़्टवेयर रेंडरिंग क्योंकि आप एक वास्तविक प्रदर्शन उपकरण में भरते नहीं कर रहे हैं प्रयोग किया जाता है, लेकिन सॉफ्टवेयर DirectX में दिनचर्या प्रतिपादन अत्यधिक अनुकूलित किया गया है तो अपने प्रदर्शन और संसाधनों की खपत है आपके द्वारा प्राप्त किए जा सकने वाले किसी भी प्रतिपादन समाधान के रूप में उतना अच्छा होगा, और शायद बेहतर होगा।
डब्ल्यूपीएफ की व्यक्तित्व जटिल ग्राफिक्स को हाथ से करने के बजाय अनुकूलित डायरेक्टएक्स कोड का उपयोग करके बनाई जा सकती है।
व्यावहारिक रूप से बोलते हुए, डब्ल्यूपीएफ सेवा के भीतर से डब्ल्यूपीएफ का उपयोग करके आपके रैम पदचिह्न में लगभग 10 एमबी जोड़ दिया जाएगा।
मुझे WPF सर्वर-पक्ष चलाने के साथ कोई स्मृति रिसाव समस्या नहीं है। मैं XAMLReader का उपयोग ऑब्जेक्ट पेड़ में XAML को पार्स करने के लिए भी कर रहा हूं और पाया है कि जब मैं ऑब्जेक्ट पेड़ का संदर्भ देना बंद करता हूं तो कचरा कलेक्टर इसे बिना किसी समस्या के एकत्र करता है। मुझे हमेशा लगा कि अगर मैं डब्ल्यूपीएफ में मेमोरी लीक में चला गया तो मैं एक अलग ऐपडोमेन में दौड़कर इसके आसपास काम करता हूं जिसे आप कभी-कभी रीसायकल करेंगे, लेकिन मुझे वास्तव में कभी सामना नहीं हुआ।
आपको एक थ्रेडिंग समस्या का सामना करना पड़ेगा कि डब्ल्यूपीएफ को एसटीए धागे की आवश्यकता होती है और डब्ल्यूसीएफ एमटीए धागे का उपयोग करता है। यह एक महत्वपूर्ण समस्या नहीं है क्योंकि आप एमटीए धागे से वही प्रदर्शन प्राप्त करने के लिए एसटीए धागे का पूल प्राप्त कर सकते हैं। मैंने एक छोटी STATHreadPool कक्षा लिखी जो संक्रमण को संभालती है। संदेश यह है:
// A simple thread pool implementation that provides STA threads instead of the MTA threads provided by the built-in thread pool
public class STAThreadPool
{
int _maxThreads;
int _startedThreads;
int _idleThreads;
Queue<Action> _workQueue = new Queue<Action>();
public STAThreadPool(int maxThreads)
{
_maxThreads = maxThreads;
}
void Run()
{
while(true)
try
{
Action action;
lock(_workQueue)
{
_idleThreads++;
while(_workQueue.Count==0)
Monitor.Wait(_workQueue);
action = _workQueue.Dequeue();
_idleThreads++;
}
action();
}
catch(Exception ex)
{
System.Diagnostics.Trace.Write("STAThreadPool thread threw exception " + ex);
}
}
public void QueueWork(Action action)
{
lock(_workQueue)
{
if(_startedThreads < _maxThreads && _idleThreads <= _workQueue.Count)
new Thread(Run) { ApartmentState = ApartmentState.STA, IsBackground = true, Name = "STAThreadPool#" + ++_startedThreads }.Start();
_workQueue.Enqueue(action);
Monitor.PulseAll(_workQueue);
}
}
public void InvokeOnPoolThread(Action action)
{
Exception exception = null;
using(ManualResetEvent doneEvent = new ManualResetEvent(false)) // someday: Recycle these events
{
QueueWork(delegate
{
try { action(); } catch(Exception ex) { exception = ex; }
doneEvent.Set();
});
doneEvent.WaitOne();
}
if(exception!=null)
throw exception;
}
public T InvokeOnPoolThread<T>(Func<T> func)
{
T result = default(T);
InvokeOnPoolThread(delegate
{
result = func();
});
return result;
}
}
स्रोत
2010-03-02 22:37:37
का उपयोग करने के लिए नीचे दिए गए कोड का उपयोग करें। –
यह प्रश्न वास्तविक है और इसे व्यक्तिपरक और तर्कवादी के रूप में बंद नहीं किया जाना चाहिए। –