2009-04-23 12 views
12

जो मैंने सी # में पाया है, से Control.Invoke विधि की आवश्यकता है कि आप कोई इनपुट पैरामीटर वाले प्रतिनिधि का उपयोग करें। क्या इसके आसपास कोई रास्ता है? मैं यूआई को किसी अन्य थ्रेड से अपडेट करने के लिए एक विधि का आह्वान करना चाहता हूं और इसमें स्ट्रिंग पैरामीटर को पास करना चाहता हूं।इनपुट पैरामीटर के साथ नियंत्रण। इन्वोक

उत्तर

22

सी # का कौन सा संस्करण आप उपयोग कर रहे हैं? यदि आप सी # 3.5 का उपयोग कर रहे हैं तो आप पैरामीटर में गुजरने से बचने के लिए बंदियों का उपयोग कर सकते हैं।

सी # 3,5
public static class ControlExtensions 
{ 
    public static TResult InvokeEx<TControl, TResult>(this TControl control, 
              Func<TControl, TResult> func) 
    where TControl : Control 
    { 
    return control.InvokeRequired 
      ? (TResult)control.Invoke(func, control) 
      : func(control); 
    } 

    public static void InvokeEx<TControl>(this TControl control, 
             Action<TControl> func) 
    where TControl : Control 
    { 
    control.InvokeEx(c => { func(c); return c; }); 
    } 

    public static void InvokeEx<TControl>(this TControl control, Action action) 
    where TControl : Control 
    { 
    control.InvokeEx(c => action()); 
    } 
} 

के साथ सुरक्षित रूप से कोड लागू अब तुच्छ हो जाता है।

this.InvokeEx(f => f.label1.Text = "Hello World"); 
this.InvokeEx(f => this.label1.Text = GetLabelText("HELLO_WORLD", var1)); 
this.InvokeEx(() => this.label1.Text = DateTime.Now.ToString()); 

के साथ सी # 2.0 यह कम तुच्छ
public class MyForm : Form 
{ 
    private delegate void UpdateControlTextCallback(Control control, string text); 
    public void UpdateControlText(Control control, string text) 
    { 
    if (control.InvokeRequired) 
    { 
     control.Invoke(new UpdateControlTextCallback(UpdateControlText), control, text); 
    } 
    else 
    { 
     control.Text = text; 
    } 
    } 
} 

यह आसान का उपयोग हो जाता है, लेकिन आप अधिक मापदंडों के लिए अधिक कॉलबैक परिभाषित करने के लिए किया है।

this.UpdateControlText(label1, "Hello world"); 
1

मुझे लगता है कि शमूएल की (उत्कृष्ट) दृष्टिकोण भी अधिक धक्का दिया जा सकता है:

एक्सटेंशन विधि:

public static void ExecuteAsync<TControl>(this TControl control, Action action) 
where TControl : Control 
{ 
    new Thread(() => 
    { 
    control.Invoke(action); 
    }) 
    .Start(); 
} 

पर्चा कोड:

private void doStuff() 
{ 
    this.ExecuteAsync(() => 
    { 
    // Do your stuff in a separate thread 
    // but having full access to local or instance variables. 

    // No (visible) threading code needs to be used here. 
    }); 
} 
6

ल्यूक के रूप में कहते हैं, नियंत्रण.आई का प्रयोग करें इस तरह nvoke ...

एक रूप में उदाहरण के लिए:

public delegate void DelegatePassMessages(string name, int value); 

public DelegatePassMessages passMessage; 

contructor में:

passMessage = new DelegatePassMessages (this.MessagesIn); 

फिर डेटा प्राप्त करने MessagesIn समारोह: फिर

public void MessagesIn(string name, int value) 
{ 

} 

अपने फॉर्म में डेटा पास करने के लिए:

formName.Invoke(formName.passMessage, new Object[] { param1, param2}); 
0

मेथडइनवॉकर प्रतिनिधि में लिपटे अज्ञात तरीकों के साथ .NET 2.0 के लिए एक सुरुचिपूर्ण विधि मिली। इस तरह हर समय अपने प्रतिनिधियों को परिभाषित करने की कोई आवश्यकता नहीं है।उदाहरण:

private void InitUI(Guid id, string typename) 
    { 
     MethodInvoker inv = delegate{tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename);}; 
     tvMatrix.Invoke(inv); 
    } 
0

क्यों नहीं

tvMatrix.Invoke((MethodInvoker) (() => { 
    tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename); 
})); 
7

कुछ अधिक संभावनाएं:

this.Invoke(new MethodInvoker(() => this.DoSomething(param1, param2))); 

या

this.Invoke(new Action(() => this.DoSomething(param1, param2))); 

या यहाँ तक कि

this.Invoke(new Func<YourType>(() => this.DoSomething(param1, param2))); 

जहां पहला विकल्प सबसे अच्छा विकल्प है, क्योंकि MethodInvoker उन उद्देश्यों के लिए अवधारणाबद्ध है और इसका बेहतर प्रदर्शन है।

1

यहां या तो Invoke() एक्सटेंशन + इनपुट पैरामीटर के साथ लैम्ब्डा एक्सप्रेशन का उपयोग करें।

का उपयोग करना: कार्रवाई (स्टार्स db)

_ccb.GetImagerFRU_PartNbr().Invoke(new Action<STARS>(dbase => _ccb.GetImagerFRU_PartNbr().Text = dbase.PartNumber(serial) ?? String.Empty), db); 
0
private void ppTrace(string tv) 
    { 
     if (_Txb1.InvokeRequired) 
     { 
      _Txb1.Invoke((Action<string>)ppTrace, tv); 
     } 
     else 
     { 
      _Txb1.AppendText(tv + Environment.NewLine); 
     } 
    } 
संबंधित मुद्दे