2010-01-21 12 views
6

मैं सिल्वरलाइट की ChildWindow ऑब्जेक्ट का उपयोग करके एक पुष्टिकरण संवाद करने का प्रयास कर रहा हूं।सिल्वरलाइट थ्रेड को रोकने के लिए संवाद की पुष्टि करें

आदर्श रूप से, मैं इसे MessageBox.Show() जैसे काम करना चाहता हूं, जहां पूरे एप्लिकेशन को उपयोगकर्ता से इनपुट प्राप्त होने तक रोक दिया जाता है।

उदाहरण के लिए:

for (int i = 0; i < 5; i++) 
{ 
    if (i==3 && MessageBox.Show("Exit early?", 
     "Iterator", MessageBoxButton.OKCancel) == MessageBoxResult.OK) 
    { 
     break; 
    } 
} 

3 में यात्रा रोक सकते हैं उपयोगकर्ता ठीक दबाता है ...

हालांकि, अगर मैं पंक्तियों के साथ कुछ करने के लिए इस प्रकार थे:

ChildWindow confirm = new ChildWindow(); 
confirm.Title = "Iterator"; 
confirm.HasCloseButton = false; 
Grid container = new Grid(); 

Button closeBtn = new Button(); 
closeBtn.Content = "Exit early"; 
closeBtn.Click += delegate { confirm.DialogResult = true; confirm.Close(); }; 
container.Children.Add(closeBtn); 

Button continueBtn = new Button(); 
continueBtn.Content = "Continue!"; 
continueBtn.Click += delegate { confirm.DialogResult = false; confirm.Close(); }; 
container.Children.Add(continueBtn); 

confirm.Content = container; 

for(int i=0;i<5;i++) { 
    if (i==3) { 
    confirm.Show(); 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) { 
     break; 
    } 
    } 
} 

यह स्पष्ट रूप से काम नहीं करेगा, क्योंकि धागा रुक गया नहीं है ... confirm.DialogResult.HasResult गलत होगा, और लूप पिछले 3 जारी रहेगा।

मैं बस सोच रहा हूं, मैं इस बारे में कैसे ठीक से जा सकता हूं। सिल्वरलाइट एकल-थ्रेडेड है, इसलिए मैं धागे को सोने के लिए नहीं डाल सकता और फिर तैयार होने पर इसे जगा सकता हूं, इसलिए मैं सोच रहा हूं कि क्या कुछ और है जो लोग सिफारिश कर सकते हैं?

मैंने तर्क को उलट दिया है - यानी, उन कार्यों को पार करना जिन्हें मैं हां/नहीं घटनाओं में करना चाहता हूं, लेकिन मेरे विशिष्ट मामले में यह काफी काम नहीं करेगा।

अग्रिम धन्यवाद!

उत्तर

11

मुझे नहीं लगता कि आप WinForms 'ShowDialog के साथ एक संदेश लूप में अपना कोड ब्लॉक कर पाएंगे।

हालांकि, अगर आप एक ही प्रभाव को प्राप्त करने iterators दुरुपयोग कर सकते हैं:

interface IAction { void Execute(Action callback); } 

public static void ExecAction(IEnumerator<IAction> enumerator) { 
    if (enumerator.MoveNext()) 
     enumerator.Current.Execute(() => ExecAction(enumerator)); 
} 

class DialogAction : ChildWindow, IAction { 
    void IAction.Execute(Action callback) { 
     //Show the window, then call callback when it's closed 
    } 
} 

IEnumerator<IAction> YourMethod() { 
    ... 
    var confirm = new DialogAction(); 
    yield return confirm; 
    if (confirm.DialogResult.HasResult && (bool)confirm.DialogResult) 
     yield break; 
    ... 
} 

इस प्रणाली का उपयोग करने के लिए आपको ExecAction(YourMethod()); लिखेंगे। ध्यान दें कि यह एक अर्ध-अवरुद्ध कॉल होगा, और मैंने इसका परीक्षण नहीं किया है।

सी # 5 की नई async विशेषताएं बिल्कुल उसी तरह काम करती हैं (वास्तव में, async कंपाइलर कोड के शुरुआती संस्करण मौजूदा इटरेटर कार्यान्वयन पर आधारित थे), लेकिन अच्छे सिंटैक्टिक समर्थन के साथ।

+1

यह बहुत प्रतिभाशाली है! मैं इसे एक शॉट दूंगा और देखता हूं कि यह कितना अच्छा काम करता है ... – AlishahNovin

+0

इसे पृष्ठभूमि थ्रेड में गणनाकर्ता को निष्पादित करने के लिए आसानी से अपनाया जा सकता है, जिससे एक बहुत ही सरल बहु थ्रेडेड यूआई वर्कफ़्लो बन जाता है। – SLaks

+0

+1। मामूली बिंदु: क्या आपका मतलब 'YourMethod' में 'उपज वापसी पुष्टिकरण' नहीं है? –

1

आप RX Framework साथ आसानी से इस शांत प्राप्त कर सकते हैं:

var continued = Observable.FromEvent<RoutedEventArgs>(continueBtn, "Click"); 

var iter = new Subject<int>(); 

var ask = iter.Where(i => i == 3).Do(_ => confirm.Show()); 

iter.Where(i => i != 3 && i < 10) 
    .Merge(ask.Zip(continued, (i, _) => i)) 
    .Do(i => Debug.WriteLine("Do something for iteration {0}", i)) 
    .Select(i => i + 1) 
    .Subscribe(iter); 

iter.OnNext(0); 

समाधान आसानी से एक संवाद को दिखाने के लिए यह निर्धारित करते हुए किसी भी नियम के पैमाने। जैसे मान लीजिए कि हम पुनरावृत्ति को अवरुद्ध करना चाहते हैं और प्रत्येक 3 पुनरावृत्तियों के उपयोगकर्ता पुष्टिकरण का अनुरोध करना चाहते हैं। आपको बस i % 3 == 0 (और i != 3i % 3 != 0 के साथ स्थिति i == 3) को प्रतिस्थापित करना है।

0

इस परियोजना को देखें http://silverlightmsgbox.codeplex.com/। यह कई उपयोगी संदेश बॉक्सों की पुष्टि, त्रुटि, जानकारी, उपयोगकर्ता इनपुट इत्यादि का एक सरल लेकिन प्रस्तुत करने योग्य कार्यान्वयन प्रस्तुत करता है और आपके लिए सहायक हो सकता है। सौभाग्य।

+0

इस प्रश्न के साथ कुछ लेना देना नहीं है - वह एक अवरुद्ध कॉल के लिए पूछ रहा है। – SLaks

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