Control.Invoke with input Parameters

后端 未结 8 587
时光说笑
时光说笑 2020-12-08 05:24

From what I\'ve found in C#, the Control.Invoke method requires that you use a delegate with no input parameters. Is there any way around this? I would like to invoke a me

相关标签:
8条回答
  • 2020-12-08 06:00

    Some more possibilities:

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

    or

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

    or even

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

    where the first option is the best one, because MethodInvoker is concepted for that purposes and has a better performance.

    0 讨论(0)
  • 2020-12-08 06:03

    Here ya go using lambda expressions with the Invoke() extension + an input parameter.

    Using: action(STARS db)

    _ccb.GetImagerFRU_PartNbr().Invoke(new Action<STARS>(dbase => _ccb.GetImagerFRU_PartNbr().Text = dbase.PartNumber(serial) ?? String.Empty), db);
    
    0 讨论(0)
  • 2020-12-08 06:05

    Found an elegant method for .net 2.0 with anonymous methods wrapped in a MethodInvoker Delegate. That way is no need to define own delegates all the time. Example:

        private void InitUI(Guid id, string typename)
        {
            MethodInvoker inv = delegate{tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename);};
            tvMatrix.Invoke(inv);
        }
    
    0 讨论(0)
  • 2020-12-08 06:08

    Which version of C# are you using? If you are using C#3.5 you can use closures to avoid passing in parameters.

    With C#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());
      }
    }
    

    Safely invoking code now becomes trivial.

    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());
    

    With C#2.0 it becomes less trivial
    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;
        }
      }
    }
    

    Using it simple, but you have to define more callbacks for more parameters.

    this.UpdateControlText(label1, "Hello world");
    
    0 讨论(0)
  • 2020-12-08 06:10

    I think Samuel's (excellent) approach can be pushed even more:

    Extension Method:

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

    Form code:

    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.
      });
    }
    
    0 讨论(0)
  • 2020-12-08 06:15

    Why not

    tvMatrix.Invoke((MethodInvoker) (() => {
        tvMatrix.Nodes[0].Nodes.Add(id.ToString(), typename);
    }));
    
    0 讨论(0)
提交回复
热议问题