Подождите с оператором возврата, пока не истечет таймер

У меня есть метод, который возвращает логическое значение, но должен подождать с возвратом значения, пока System.Timers.Timer не вызовет истекшее событие, потому что значение, которое я хочу вернуть, установлено в истекшем событии таймера.

public static bool RecognizePushGesture()
{
    List<Point3D> shoulderPoints = new List<Point3D>();
    List<Point3D> handPoints = new List<Point3D>();
    shoulderPoints.Add(Mouse.shoulderPoint);
    handPoints.Add(Mouse.GetSmoothPoint());
    Timer dt = new Timer(1000);
    bool click = false;

    dt.Elapsed += (o, s) =>
    {
        shoulderPoints.Add(Mouse.shoulderPoint);
        handPoints.Add(Mouse.GetSmoothPoint());
        double i = shoulderPoints[0].Z - handPoints[0].Z;
        double j = shoulderPoints[1].Z - handPoints[1].Z;
        double k = j - i;
        if (k >= 0.04)
        {
            click = true;
            dt.Stop();
        }
    };

    dt.Start();

    //should wait with returning the value until timer raises elapsed event
    return click;
}

Спасибо, Тим


person Tim T    schedule 23.10.2012    source источник
comment
Если вы хотите в основном делать что-то синхронно (блокировать, пока это не будет завершено), почему вы вообще запускаете таймер? Какой здесь контекст? (GUI, не GUI, какой GUI?)   -  person Jon Skeet    schedule 23.10.2012
comment
Если он сработает только один раз... зачем использовать таймер? Если вы не против заблокировать текущий поток, вы можете использовать Sleep() (или вообще ничего). Если вы можете выполнять какую-то другую обработку во время ожидания первого прошедшего события, почему бы не использовать поток/задачу (к которой вы присоединитесь, когда закончите параллельную работу)?   -  person Adriano Repetti    schedule 23.10.2012
comment
хорошо, контекст - это Kinect для Windows, мне нужно сравнить координаты z рук и плечевых суставов с задержкой в ​​1 секунду   -  person Tim T    schedule 23.10.2012
comment
я не хочу, чтобы RecognizePushGesture() блокировал мой текущий поток   -  person Tim T    schedule 23.10.2012
comment
Вызывающий объект @TimT RecognizePushGesture() будет ждать возвращаемого значения, поэтому он ДОЛЖЕН ждать. Если это не так, вам лучше также провести рефакторинг вызывающей стороны (и в этом случае не использовать таймер): сделайте ее асинхронной и замените таймер простым Thread.Sleep(1000).   -  person Adriano Repetti    schedule 23.10.2012
comment
tghats тоже хорошая идея, спасибо за вашу помощь, ребята   -  person Tim T    schedule 23.10.2012
comment
Альтернативой было бы позволить RecognizePushGesture принимать делегата в качестве параметра, который будет работать как обратный вызов всякий раз, когда k >= 0.04.   -  person ebb    schedule 23.10.2012


Ответы (1)


Использовать автосброс события

public static bool RecognizePushGesture()
    {
        AutoResetEvent ar = new AutoResetEvent(false);
        List<Point3D> shoulderPoints = new List<Point3D>();
        List<Point3D> handPoints = new List<Point3D>();
        shoulderPoints.Add(Mouse.shoulderPoint);
        handPoints.Add(Mouse.GetSmoothPoint());
        Timer dt = new Timer(1000);
        bool click = false;
        dt.Elapsed += (o, s) =>
        {
            shoulderPoints.Add(Mouse.shoulderPoint);
            handPoints.Add(Mouse.GetSmoothPoint());
            double i = shoulderPoints[0].Z - handPoints[0].Z;
            double j = shoulderPoints[1].Z - handPoints[1].Z;
            double k = j - i;
            if (k >= 0.04)
            {
                click = true;
                dt.Stop();
            }
            ar.Set();
        };
        dt.Start();

        //should wait with returning the value until timer raises elapsed event
        ar.WaitOne();
        return click;
    }
person Amiram Korach    schedule 23.10.2012
comment
Хорошо, проблема решена, только что запустил RecognizePushGesture() в собственном потоке. это больше не блокирует мою текущую тему, спасибо за вашу помощь :) - person Tim T; 23.10.2012