我有一个本应该是线程安全的小方法。一切正常,直到我希望它具有回报价值而不是虚空。如何在调用BeginInvoke时获得返回值?
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
varControl.BeginInvoke(new MethodInvoker(() => readControlText(varControl)));
} else {
string varText = varControl.Text;
return varText;
}
}
编辑:我想在这种情况下让BeginInvoke不是nessecary,因为我需要来自GUI的值才能继续线程。所以使用Invoke也很好。只是不知道如何在以下示例中使用它来返回值。
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;
}
}
但不确定如何使用该代码获取价值;)
答案 0 :(得分:57)
您必须调用(),以便等待函数返回并获取其返回值。您还需要另一个委托类型。这应该有效:
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 :(得分:17)
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);
}
}
答案 2 :(得分:4)
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;
}
答案 3 :(得分:2)
如果你想从你的方法返回值,你不应该使用该方法的异步版本,你应该使用.Invoke(...)
。哪个是同步的,即它将执行您的委托,并且在完成之前不会返回。在您的示例中,BeginInvoke将发送执行您的委托的请求,并立即返回。所以没有什么可以回归的。
答案 4 :(得分:1)
这是你想要的吗?
// 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);
答案 5 :(得分:0)
delegate string StringInvoker();
string GetControlText()
{
if (control.InvokeRequired)
{
string controltext = (string)control.Invoke(new StringInvoker(GetControlText));
return(controltext);
}
else
{
return(control.Text);
}
}
//简单&amp;优雅,但需要等待另一个线程执行委托;但如果没有结果你就无法继续......