मैं सिमुलेशन सिस्टम पर काम कर रहा हूं कि, अन्य चीजों के साथ, अलग-अलग अनुरूपित समय चरणों में कार्यों को निष्पादित करने की अनुमति देता है। निष्पादन सिमुलेशन थ्रेड के संदर्भ में होता है, लेकिन, सिस्टम का उपयोग कर 'ऑपरेटर' के परिप्रेक्ष्य से, वे असीमित व्यवहार करना चाहते हैं। शुक्र है कि आसान 'async/await' कीवर्ड के साथ टीपीएल, यह काफी सरल बनाता है।अक्सर पुन: संक्रमित घटनाओं पर टीपीएल पूर्ण होने के लिए कुशल सिग्नलिंग कार्य
public Task CycleExecutedEvent()
{
lock (_cycleExecutedBroker)
{
if (!IsRunning) throw new TaskCanceledException("Simulation has been stopped");
return _cycleExecutedBroker.RegisterForCompletion(CycleExecutedEventName);
}
}
यह मूल रूप से एक नया TaskCompletionSource पैदा कर रही है और फिर एक टास्क लौटने: मैं इस तरह सिमुलेशन पर एक आदिम विधि है। इस कार्य का उद्देश्य सिमुलेशन पर नया 'ExecuteCycle' होने पर इसकी निरंतरता को निष्पादित करना है।
मैं तो इस तरह की कुछ विस्तार तरीकों:
public static async Task WaitForDuration(this ISimulation simulation, double duration)
{
double startTime = simulation.CurrentSimulatedTime;
do
{
await simulation.CycleExecutedEvent();
} while ((simulation.CurrentSimulatedTime - startTime) < duration);
}
public static async Task WaitForCondition(this ISimulation simulation, Func<bool> condition)
{
do
{
await simulation.CycleExecutedEvent();
} while (!condition());
}
ये एक 'ऑपरेटर' नजरिए से दृश्यों का निर्माण, शर्तों के आधार पर कार्रवाई करने और नकली समय की अवधि के लिए प्रतीक्षा करने के लिए बहुत आसान कर रहे हैं, तो,। जिस मुद्दे में मैं दौड़ रहा हूं वह यह है कि साइकिल-सब्सक्रिप्टेड अक्सर होता है (लगभग हर कुछ मिलीसेकंड अगर मैं पूरी तरह से गतिशील गति से चल रहा हूं)। चूंकि ये 'प्रतीक्षा' सहायक तरीके प्रत्येक चक्र पर एक नया 'प्रतीक्षा' पंजीकृत करते हैं, इसलिए यह कार्यसंगठन स्रोतों में एक बड़ा कारोबार का कारण बनता है।
मैंने अपना कोड प्रोफाइल किया है और मुझे पता चला है कि मेरे कुल CPU समय का लगभग 5.5% इन समापनों में खर्च किया जाता है, जिनमें से केवल 'नगण्य' प्रतिशत को 'सक्रिय' कोड में खर्च किया जाता है। ट्रिगरिंग स्थितियों के वैध होने की प्रतीक्षा करते समय प्रभावी ढंग से नए समय को पूरा करने में खर्च किया जाता है।
मेरा प्रश्न: मैं 'ऑपरेटर व्यवहार' लिखने के लिए एसिंक/प्रतीक्षा पैटर्न की सुविधा को बनाए रखने के दौरान यहां प्रदर्शन में सुधार कैसे कर सकता हूं? मुझे लगता है कि मुझे लाइटर-वेट और/या पुन: प्रयोज्य टास्क कॉम्प्लेशनसोर्स की तरह कुछ चाहिए, यह देखते हुए कि ट्रिगरिंग घटना इतनी बार होती है।
मैं थोड़ा और अधिक शोध कर रहा हूँ और यह लग रहा है एक अच्छा विकल्प की तरह Awaitable पैटर्न, जो सीधे घटना में बाँध सकती के एक कस्टम कार्यान्वयन के लिए हो सकता है, का एक समूह की आवश्यकता को समाप्त कार्य पूर्णीकरण स्रोत और कार्य उदाहरण। कारण यह उपयोगी हो सकता है कि CycleExecutedEvent का इंतजार करने वाली कई अलग-अलग निरंतरताएं हैं और उन्हें अक्सर प्रतीक्षा करने की आवश्यकता है। तो आदर्श रूप से मैं निरंतर कॉलबैक को कतारबद्ध करने का एक तरीका देख रहा हूं, फिर जब भी घटना होती है तो कतार में सबकुछ वापस कॉल करें। मैं खुदाई रखूंगा, लेकिन अगर लोगों को ऐसा करने का एक साफ तरीका पता है तो मैं किसी भी मदद का स्वागत करता हूं।
किसी को भी भविष्य में इस सवाल को ब्राउज़ कर के लिए, यहाँ रिवाज है awaiter मैं एक साथ रखा:
public sealed class CycleExecutedAwaiter : INotifyCompletion
{
private readonly List<Action> _continuations = new List<Action>();
public bool IsCompleted
{
get { return false; }
}
public void GetResult()
{
}
public void OnCompleted(Action continuation)
{
_continuations.Add(continuation);
}
public void RunContinuations()
{
var continuations = _continuations.ToArray();
_continuations.Clear();
foreach (var continuation in continuations)
continuation();
}
public CycleExecutedAwaiter GetAwaiter()
{
return this;
}
}
और सिम्युलेटर में:
private readonly CycleExecutedAwaiter _cycleExecutedAwaiter = new CycleExecutedAwaiter();
public CycleExecutedAwaiter CycleExecutedEvent()
{
if (!IsRunning) throw new TaskCanceledException("Simulation has been stopped");
return _cycleExecutedAwaiter;
}
यह थोड़ा अजीब है, के रूप में प्रतीक्षाकर्ता कभी भी पूर्ण रिपोर्ट नहीं करता है, लेकिन आग पंजीकृत होने पर कॉल पूरा होने के लिए जारी है; फिर भी, यह इस एप्लिकेशन के लिए अच्छा काम करता है। इससे सीपीयू ओवरहेड 5.5% से 2.1% तक कम हो जाता है। इसकी संभावना अभी भी कुछ tweaking की आवश्यकता होगी, लेकिन यह मूल पर एक अच्छा सुधार है।
अरे, मेरे सामने एक मिनट पहले अपने प्रश्न का उत्तर देना उचित नहीं है! :-) – svick
@ एसविक, अभी तक इसका पूरी तरह उत्तर नहीं दिया गया है; मुझे अभी भी कस्टम प्रतीक्षाकर्ता बनाने का तरीका जानने की जरूरत है। :) लिंक के लिए धन्यवाद; वे काफी उपयोगी हैं। –
@ डैन ब्रायंट: आपको अपने प्रश्न का उत्तर देना चाहिए ... अपने स्वयं के प्रश्न के बजाए उत्तर के रूप में। – user7116