Как написать Timeutable методы в C # - PullRequest
2 голосов
/ 08 февраля 2011

У меня есть методы, которые занимают больше времени и требуют большого количества операций с базой данных. Я хочу обернуть эти методы в метод с временным графиком, чтобы, если он не вызывался в течение постоянного времени, я выполнял откат.

Есть ли способ сделать это, также мне нужно запускать метод только в основном потоке, потому что используемые мной сторонние com-объекты не могут быть выполнены в фоновом потоке.

Любые предложения будут высоко оценены.

С уважением,

Бибек Давади

Ответы [ 3 ]

2 голосов
/ 08 февраля 2011
1 голос
/ 08 февраля 2011

Я собрал воедино решение, подобное тому, с которым связано, за исключением того, что я использовал Thread.Interrupt () вместо Thread.Abort (), полагая, что это будет немного добрее для основного потока.Проблема в том, что Thread.Interrupt () не будет прерывать заблокированный вызов, поэтому во многих случаях это неудовлетворительно.Thread.Abort () является опасным вызовом, и его следует по возможности избегать.Выбери свой яд.

Для чего это стоит, это моя реализация:

public static class AbortableProc
{

    public static void Execute(Action action, Action timeoutAction, int milli)
    {
        Thread currThread = Thread.CurrentThread;
        object stoppedLock = new object();
        bool stopped = false;
        bool interrupted = false;

        Thread timer = new Thread(() =>
        {
            Thread.Sleep(milli);
            lock (stoppedLock)
            {
                if (!stopped)
                {
                    currThread.Interrupt();
                    stopped = true;
                    interrupted = true;
                }
            }
        });
        timer.Start();

        try
        {
            action();
            lock (stoppedLock)
            {
                stopped = true;
            }
        }
        catch (ThreadInterruptedException)
        {
        }
        if (interrupted)
        {
            timeoutAction();
        }
    }
}

Для ухмылок я добавил timeoutAction, чтобы ты мог использовать его в этом режиме:

AbortableProc.Execute(
    () => { Process(kStarting); Process(kWorking); Process(kCleaningUp); },
    () => { if (IsWorking()) CleanUp(); }
};
1 голос
/ 08 февраля 2011

Я был с вами, пока вы не сказали, что он нужен для запуска в главном потоке. Я не думаю, что это возможно, как вы описываете.

Проблема в том, что вам понадобится как минимум два потока для выполнения синхронизации и фактической работы, и ни один из них не может быть основным потоком, потому что таймер не будет использовать основной поток, и потому что вы ' Я захочу завершить операцию, которая, если бы это был главный поток, закрыла бы все приложение. Обычно вы делаете это, устанавливая класс-оболочку, который запускается из основного потока и настраивает фоновый поток для операции и таймер.

Почему именно сторонняя библиотека должна вызываться из основного потока?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...