如何从c#中的另一个线程上的方法获取结果

时间:2012-12-14 21:40:10

标签: c# asynchronous invoke

我在这里很困惑,不确定框架(4.0)是否支持我在网上找到的一些答案。

我有以下结构

public class Form1() 
{

    public int GenerateID(OtherThreadObj oto)
    {
       int result;
       if (this.InvokeRequired)
                {
                    return (int)this.Invoke((MethodInvoker)delegate { GenerateIDSafe(oto); });
                // now this doesn't work obviously. I was looking at .begininvoke, end, etc and got really lost there

                }
                else
                {
               return   GenerateIDSafe(oto);
                }
    }


    private int GenerateIDSafe(OtherThreadObj oto)
    {

    return oto.id.ToSuperID(); // Assume ToSuperID some extension method.

    }

    }

现在,Idea将从另一个Thread调用Generate ID并获取     返回值。

    public class OtherThreadObj 
    {

    private Form1 parentform;

    private int GetSuperID()
    {

    return parentform.GenerateID(this);

    }
    }

所以显然上面的情况并不好,因为我没有在.Invoke上得到正确的回报。我完全迷失了如何正确地做到这一点。

4 个答案:

答案 0 :(得分:1)

你快到了那里:

public int GenerateID(OtherThreadObj oto)
{
    int result;
    this.Invoke((MethodInvoker)delegate { result = GenerateIDSafe(oto); });
    return result;
}

答案 1 :(得分:1)

使用回调函数或委托。这是一个函数,您传递给另一个函数,以便在完成异步处理后调用。

在下面的示例中,GetMeValue异步调用GetValue,GotTheValue用于回调。组织事物的更​​好方法是将回调直接传递给GetValue并让它以异步方式运行。例如,如果您正在寻找更好的示例,就可以在Silverlight中进行网络连接。

更好的方法是了解C#中的“异步”运算符

public class Producer{ 
    public static int GetValue(){
    //... long running operation
    }
}


public class FormConsumer{


   public void GetMeValue(){
       int v = 0;
       // setting up for async call
       Action asyncCall = () => { v = Producer.GetValue();};

       // this is the delegate that will be called when async call is done
       AsyncCallback = (acbk)=> {
            this.Invoke((MethodInvoker)delegate{ 
                GotTheValue(v)
            });
       };

       // execute the call asynchronously
       asyncCall.BeginInvoke(acbk, null); 
   }

   public void GotTheValue(int v){
     // this gets called on UI thread 
   }
}

答案 2 :(得分:0)

在.net 4.0中,您可以使用任务并行库(TPL),这使得多线程比以前的范例更容易。下面的代码在不同的线程上运行方法“GenerateID”。然后我得到结果并将其显示在我的主线程上。

using System.Threading.Tasks;

namespace Console
{
    class Program
    {
        static void Main(string[] args)
        {
            Task<int> task = Task<int>.Factory.StartNew(() =>
                {
                    return GenerateID();
                 });

            int result = task.Result;

            System.Console.WriteLine(result.ToString());

            System.Console.ReadLine();
        }

        static private int GenerateID()
        {
            return 123;
        }
    }
}

希望这会有所帮助。

答案 3 :(得分:-1)

或另一个说清楚的例子:

void do_access ()
{
   if (ctrl.InvokeRequired) {      
      ctrl.Invoke (new MethodInvoker (do_access));
      return;
   }
   ctrl.Text = "Hello World!";
}