0

オプションで新しいスレッドを開始し、いくつかの処理を実行してから、オブジェクトで別のメソッドを呼び出すサードパーティ コードを呼び出す必要があります。必要なのは、サードパーティの処理が完了するのを待ってから、元のメソッドから戻ることです。つまり、次のようなクラスがあります (C#):

class MyClass: IThirdPartyInterface {
    void MyMethod() {
        //some preprocessing
        //call a 3rd party static method
        ThirdParty.DoSomething(this);
     }
    void FinishedProcessing() {
        //some postprocessing
        //???
    }
}

DoSomething で開始されたスレッドが実行を終了し、FinishedProcessing メソッドを呼び出した後にのみ戻るように、MyMethod を変更したいと考えています。スレッドはサード パーティのコードによって開始されるため、アクセスできないため、ここでは Thread.Join を使用できません。それで、私は代わりに何をしますか?

4

3 に答える 3

3

System.Threading.AutoResetEvent を使用する必要があります。次のようになります。

class MyClass: IThirdPartyInterface {
    AutoResetEvent _event = new AutoResetEvent(false);
    void MyMethod() {
        ThirdParty.DoSomething(this);
        _event.WaitOne();
    }
    void FinishedProcessing() {
        _event.Set();
    }
}

FinishedProcessing メソッドがサードパーティ クラスによって呼び出された後もスレッドが実行され続ける場合は、少し異なります。

class MyClass: IThirdPartyInterface {
    AutoResetEvent _event = new AutoResetEvent(false);
    Thread _thread;
    void MyMethod() {
        ThirdParty.DoSomething(this);
        _event.WaitOne();
        _thread.Join();
    }
    void FinishedProcessing() {
        _thread = Thread.CurrentThread;
        _event.Set();
    }
}
于 2013-02-16T21:41:01.510 に答える
0

ThirdParty.DoSomething が非同期パターンをサポートしていない場合は、ファイナライザーで追加のプロキシを使用できます。ただし、「while(myBoolFlag){}」のようにアプリケーションのパフォーマンスに影響を与える可能性があります。

class Program
{
    static void Main(string[] args)
    {
        var list = new List<ManualResetEvent>();
        for (var i = 0; i < 10000; i++)
        {
            var m = new ManualResetEvent(false);
            list.Add(m);
            new Thread(Start).Start(m);

            if (i > 0 && (i % 10) == 0)
                for (int j = i - 10; j < i; j++)
                {
                    list[j].WaitOne(1000);// wait signal
                    GC.Collect(); //force finalizer
                    A.Print();
            }
        }
    }

    private static void Start(object obj)
    {
        new A(obj as ManualResetEvent, null);
    }
}

public class A : IThirdPartyInterface
{
    public static long time1;
    public static long count1;

    private DateTime start = DateTime.Now;
    private ManualResetEvent _stop;
    private IThirdPartyInterface _origin;
    public A(ManualResetEvent stop, IThirdPartyInterface origin)
    {
        _stop = stop;
        _origin = origin;
    }

    ~A()
    {
        Interlocked.Increment(ref count1);
        Interlocked.Add(ref time1, (long)(DateTime.Now - start).TotalMilliseconds);
        _stop.Set(); //send signal
    }

    public static void Print()
    {
        Console.Write("\r" + A.time1 + "\\" + A.count1 + "    ");
        if (A.count1 != 0)
            Console.Write((A.time1 / A.count1).ToString());
    }
}
于 2013-02-16T21:38:57.373 に答える
0

MyMethod() を非同期にしてから、カスタム await メソッド内でサードパーティ メソッドを実行します。次のように moething します。

private async void MyMethod()
{
    var result = await WaitAsynchronouslyAsync();
}

public async Task<string> WaitAsynchronouslyAsync()
{
    await ThirdParty.DoSomething(this);
    return "Finished";
}
于 2013-02-16T20:12:39.147 に答える