2010-02-06 10 views
31

çağrıldığında nasıl dönüş değeri elde edilir Bu iş parçacığı güvenli olması gereken bir yöntem var. Her şey, boşluk yerine dönüş değeri olmasını istediğim kadar çalışır. BeginInvoke çağrıldığında dönüş değerini nasıl alabilirim?BeginInvoke/Invoke C#

public static string readControlText(Control varControl) { 
     if (varControl.InvokeRequired) { 
      varControl.BeginInvoke(new MethodInvoker(() => readControlText(varControl))); 
     } else { 
      string varText = varControl.Text; 
      return varText; 
     } 

    } 

Düzenleme: haiz sanırım Beginınvoke iplik devam etmeden önce ben GUI değeri gerektiğinden bu durumda nessecary değildir. Yani Invoke kullanarak da iyidir. Değeri döndürmek için aşağıdaki örnekte nasıl kullanıldığına dair hiçbir ipucu yoktur.

private delegate string ControlTextRead(Control varControl); 
    public static string readControlText(Control varControl) { 
     if (varControl.InvokeRequired) { 
      varControl.Invoke(new ControlTextRead(readControlText), new object[] {varControl}); 
     } else { 
      string varText = varControl.Text; 
      return varText; 
     } 

    } 

Ama ya o kodu kullanarak değeri almak için nasıl emin;)

+0

Bir çağrıda döndürülen değerle çalışmanız gerekirse, bunun nedeni "devam eden geçiş stili" desenine gereksiniminiz olması gerekir. Hangisi async, 'bekliyor 've' Görev' ile hafifletilebilir. –

cevap

49

İşlevin geri dönüşünü ve dönüş değerini elde etmesini beklemek için Invoke() yapmanız gerekir. Ayrıca başka bir temsilci türüne de ihtiyacınız olacak. Bu işe gerektiğini: Bir BeginInvoke çağrısından bir dönüş değeri elde etmek için kullanılabilir

public static string readControlText(Control varControl) { 
    if (varControl.InvokeRequired) { 
    return (string)varControl.Invoke(
     new Func<String>(() => readControlText(varControl)) 
    ); 
    } 
    else { 
    string varText = varControl.Text; 
    return varText; 
    } 
} 
1

sen, yöntemin zaman uyumsuz bir sürümünü kullanıyor olmamalıdır size yönteminden bir dönüş değeri isterseniz, .Invoke(...) kullanmalıdır . Senkronize olan, yani temsilcinizi yürütecek ve tamamlanana kadar geri dönmeyecek. Örneğinizdeki haliyle, BeginInvoke, temsilcinizi yürütme isteğini gönderecek ve hemen geri dönecektir. Yani geri dönmek için bir şey yok.

+0

Geri döndüğüm sürece Invoke veya BeginInvoke olabilir. Tek ihtiyacım olan, diğer iş parçacığından gelen birleşik giriş kutusunun veya metin kutusunun değerini okumak. – MadBoy

1

İstediğiniz gibi bir şey var mı?

// begin execution asynchronously 
IAsyncResult result = myObject.BeginInvoke("data.dat", null, null); 

// wait for it to complete 
while (result.IsCompleted == false) { 
    // do some work 
    Thread.Sleep(10); 
    } 

// get the return value 
int returnValue = myObject.EndInvoke(result); 
+0

Tam olarak değil. BeginInvoke kullanımı sadece ComboBox veya TextBox değerini okumak istediğimden ve diğer komutları yürütmek için önemli olduğundan, nessecary kullanımı değil sanırım. Böylece onu Invoke'da kullanabilirdim. Örneğinizi nasıl kullanabileceğimi bilmiyorum çünkü ana amacı başka bir iş parçacığı yöntemini çağırmak, gui değerini okumak ve programa geri dönebilmek için bana geri dönmektir. – MadBoy

3
public static string readControlText(Control varControl) 
{ 
    if (varControl.InvokeRequired) 
    { 
     string res = ""; 
     var action = new Action<Control>(c => res = c.Text); 
     varControl.Invoke(action, varControl); 
     return res; 
    } 
    string varText = varControl.Text; 
    return varText; 
} 
+0

nobugz çözümüne benziyor ama bana bakışı daha temiz görünüyor :-) – MadBoy

+0

Evet, kabul ediyorum. Çözümü gönderdiğimde henüz nobugz çözüm göremiyorum :) –

16

EndInvoke. Örneğin:

public static void Main() 
    { 
     // The asynchronous method puts the thread id here. 
     int threadId; 

     // Create an instance of the test class. 
     AsyncDemo ad = new AsyncDemo(); 

     // Create the delegate. 
     AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod); 

     // Initiate the asychronous call. 
     IAsyncResult result = caller.BeginInvoke(3000, 
      out threadId, null, null); 

     Thread.Sleep(0); 
     Console.WriteLine("Main thread {0} does some work.", 
      Thread.CurrentThread.ManagedThreadId); 

     // Call EndInvoke to wait for the asynchronous call to complete, 
     // and to retrieve the results. 
     string returnValue = caller.EndInvoke(out threadId, result); 

     Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", 
      threadId, returnValue); 
    } 
} 
+0

Benim durumumda nobugz çözümü mükemmel ve tam olarak ne gerekli olsa da genel olarak iyi bir örnek. – MadBoy

0
delegate string StringInvoker(); 
    string GetControlText() 
    { 
     if (control.InvokeRequired) 
     { 
      string controltext = (string)control.Invoke(new StringInvoker(GetControlText)); 
      return(controltext); 
     } 
     else 
     { 
      return(control.Text); 
     } 
    } 

// zarif & basit ama temsilci yürütmek başka bir iş parçacığı için beklemek gereklidir; Ancak, sonuçlar olmadan devam edemezseniz ...