1

我在这里很困惑,不确定框架(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.

    }

    }

现在的想法是从另一个线程调用生成 ID 并获取该返回值。

    public class OtherThreadObj 
    {

    private Form1 parentform;

    private int GetSuperID()
    {

    return parentform.GenerateID(this);

    }
    }

很明显,上述内容并不好,因为我没有在.Invoke 上得到正确的回报。我完全不知道如何正确地做到这一点。

4

4 回答 4

1

你几乎在那里:

public int GenerateID(OtherThreadObj oto)
{
    int result;
    this.Invoke((MethodInvoker)delegate { result = GenerateIDSafe(oto); });
    return result;
}
于 2012-12-14T22:00:23.387 回答
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 
   }
}
于 2012-12-14T22:01:12.600 回答
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;
        }
    }
}

希望这可以帮助。

于 2012-12-14T22:04:48.983 回答
-1

或者另一个说明清楚的例子:

void do_access ()
{
   if (ctrl.InvokeRequired) {      
      ctrl.Invoke (new MethodInvoker (do_access));
      return;
   }
   ctrl.Text = "Hello World!";
}
于 2012-12-14T22:09:20.280 回答