如何在c#中调用BeginInvoke/Invoke方法时获得返回值

时间:2022-01-29 04:27:51

I've this little method which is supposed to be thread safe. Everything works till i want it to have return value instead of void. How do i get the return value when BeginInvoke is called?

这个小方法应该是线程安全的。一切都在工作,直到我希望它有回报价值而不是空虚。如何在调用BeginInvoke时获得返回值?

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

    }

Edit: I guess having BeginInvoke is not nessecary in this case as i need value from GUI before the thread can continue. So using Invoke is good as well. Just no clue how to use it in following example to return value.

编辑:我想在这种情况下,拥有BeginInvoke方法不是必需的,因为在线程继续之前,我需要GUI的值。所以使用调用也很好。只是不知道如何在下面的示例中使用它来返回值。

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;
        }

    }

But not sure how to get value using that code either ;)

但也不知道如何使用这些代码来获取价值;)

6 个解决方案

#1


51  

You have to Invoke() so you can wait for the function to return and obtain its return value. You'll also need another delegate type. This ought to work:

您必须调用(),以便等待函数返回并获取其返回值。您还需要另一个委托类型。这应该工作:

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;
  }
}

#2


17  

EndInvoke may be used to get a return value from a BeginInvoke call. For example:

EndInvoke用于从BeginInvoke调用获取返回值。例如:

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

#3


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;
}

#4


1  

If you want a return value from you method, you shouldn't be using async version of the method, you should use .Invoke(...). Which is synchronous, that is it will execute your delegate, and won't return until it's complete. In your example as it is now, BeginInvoke will send the request to execute your delegate, and return right away. So there is nothing to return.

如果您想从您的方法中获得一个返回值,您不应该使用该方法的异步版本,您应该使用. invoke(…)。它是同步的,它将执行你的委托,直到完成它才返回。在当前的示例中,BeginInvoke将发送请求来执行委托,并立即返回。所以没有什么可以回报的。

#5


1  

Is something like this what you wanted?

像这样的东西是你想要的吗?

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

#6


0  

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

//simple & elegant but it is needed to wait for another thread to execute delegate; however if you cannot proceed without the results...

//简单而优雅,但需要等待另一个线程执行委托;然而,如果你不能在没有结果的情况下继续前进……

#1


51  

You have to Invoke() so you can wait for the function to return and obtain its return value. You'll also need another delegate type. This ought to work:

您必须调用(),以便等待函数返回并获取其返回值。您还需要另一个委托类型。这应该工作:

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;
  }
}

#2


17  

EndInvoke may be used to get a return value from a BeginInvoke call. For example:

EndInvoke用于从BeginInvoke调用获取返回值。例如:

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

#3


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;
}

#4


1  

If you want a return value from you method, you shouldn't be using async version of the method, you should use .Invoke(...). Which is synchronous, that is it will execute your delegate, and won't return until it's complete. In your example as it is now, BeginInvoke will send the request to execute your delegate, and return right away. So there is nothing to return.

如果您想从您的方法中获得一个返回值,您不应该使用该方法的异步版本,您应该使用. invoke(…)。它是同步的,它将执行你的委托,直到完成它才返回。在当前的示例中,BeginInvoke将发送请求来执行委托,并立即返回。所以没有什么可以回报的。

#5


1  

Is something like this what you wanted?

像这样的东西是你想要的吗?

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

#6


0  

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

//simple & elegant but it is needed to wait for another thread to execute delegate; however if you cannot proceed without the results...

//简单而优雅,但需要等待另一个线程执行委托;然而,如果你不能在没有结果的情况下继续前进……