9

की पोर्टेबल वर्ग पुस्तकालय बराबर .नेट, विंडोज 8 और विंडोज फोन 7 में मैं इस के समान कोड है:Dispatcher.Invoke या Dispatcher.RunAsync

public static void InvokeIfRequired(this Dispatcher dispatcher, Action action) 
{ 
    if (dispatcher.CheckAccess()) 
    { 
     action(); 
    } 
    else 
    { 
     dispatcher.Invoke(action); 
    } 
} 

मैं कैसे पोर्टेबल वर्ग पुस्तकालय में कुछ करना चाहते हैं? इस के एक मंच अज्ञेय कार्यान्वयन करना अच्छा लगेगा। मेरा विचार टीपीएल का उपयोग करना है जो WP7 में उपलब्ध नहीं है लेकिन निश्चित रूप से जल्द ही होगा।

// PortableDispatcher must be created on the UI thread and then made accessible 
// maybe as a property in my ViewModel base class. 
public class PortableDispatcher 
{ 
    private TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 

    public void Invoke(Action action) 
    { 
     if (Alread on UI thread. How would I do this.) 
     { 
      action(); 
     } 

     Task.Factory.StartNew(
      action, 
      CancellationToken.None, 
      TaskCreationOptions.None, 
      taskScheduler); 
    } 
} 

केवल एक चीज जो मुझे अनिश्चित है, यह है कि इसका प्रदर्शन प्रभाव क्या होगा। शायद मैं कुछ परीक्षण करूंगा।

उत्तर

2

:

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

public Task RunAsync(Action action) 
{ 
    TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>(); 

    if (this.synchronizationContext == SynchronizationContext.Current) 
    { 
     try 
     { 
      action(); 
      taskCompletionSource.SetResult(null); 
     } 
     catch (Exception exception) 
     { 
      taskCompletionSource.SetException(exception); 
     } 
    } 
    else 
    { 
     // Run the action asyncronously. The Send method can be used to run syncronously. 
     this.synchronizationContext.Post(
      (obj) => 
      { 
       try 
       { 
        action(); 
        taskCompletionSource.SetResult(null); 
       } 
       catch (Exception exception) 
       { 
        taskCompletionSource.SetException(exception); 
       } 
      }, 
      null); 
    } 

    return taskCompletionSource.Task; 
} 
+2

नाइस के लिए पूछता है। ऐसा लगता है कि आपने एक वर्ग बनाया है, लेकिन केवल अन्य लोगों के लिए विधि (इसलिए स्पष्ट) नोट पोस्ट किया है। यह सिंक्रनाइज़ेशन कॉन्टेक्स्ट को उस थ्रेड में असाइन किया जाना चाहिए जिसे आप विधि को कॉल करने से पहले क्रिया को चलाने के लिए चाहते हैं। मैंने वास्तव में थोड़ा सा संशोधित किया और एक एक्सटेंशन बनाया: सार्वजनिक कार्य RunAsync (यह सिंक्रनाइज़ेशन कॉन्टेक्स्ट संदर्भ, क्रिया क्रिया)। अब यह मूल उत्तर की तरह है क्योंकि यह अकेले खड़ा हो सकता है। दोनों उत्तरों का सबसे अच्छा। :) – Wes

13

आप SynchronizationContext.Post या विधि भेज सकते हैं। यह पोर्टेबल है, और जब आप एक प्रेषक के साथ यूआई फ्रेमवर्क का उपयोग करते हैं तो वर्तमान सिंक्रनाइज़ेशन संदर्भ डिस्पैचर को काम सौंपेगा। TPL के आगमन के साथ

void InvokeIfRequired(this SynchroniationContext context, Action action) 
{ 
    if (SynchroniationContext.Current == context) 
    { 
     action(); 
    } 
    else 
    { 
     context.Send(action) // send = synchronously 
     // context.Post(action) - post is asynchronous. 
    } 
} 
+0

अच्छा एक। मैं प्रेषक के लिए ऊपर उपयोग की जाने वाली एक्सटेंशन विधि कैसे बनाऊंगा। विशिष्ट रूप से आप कैसे जांचते हैं कि आप प्रेषक करने के बजाए यूआई थ्रेड पर पहले से चल रहे हैं या नहीं। चेकएप()। –

+0

भी BeginInvoke के समकक्ष पोस्ट करें और Invoke के समतुल्य भेजें? –

+1

आपको पोस्ट करने से पहले जांचने की आवश्यकता नहीं है। पोस्ट पहले से ही उचित जांच करता है। –

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