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.

    }

    }

ここでのアイデアは、Generate ID を別の Thread から呼び出して、その戻り値を取得することです。

    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 では、Task Parallel Library (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 に答える