Неблокирующее ожидание без TPL в 3.5

Как я могу выполнить ожидание без блокировки потока и без TPL «ContinueWith»? Например в 3.5? Я знаю о портированной версии TPL для 3.5 (командой RX), но мне любопытно узнать, какие примитивы потоковой передачи я могу использовать для этого (... что стоит за сценами TPL). А какие есть альтернативы ContinueWith в TPL?

// будет ли этот обработчик блокировать поток во время операции асинхронного ввода-вывода?

public class AsyncHandler : IHttpAsyncHandler
    {
        public void ProcessRequest(HttpContext ctx)
        {
            // not used
        }

    public bool IsReusable
    {
        get { return false; }
    }

    public IAsyncResult BeginProcessRequest(HttpContext ctx,
                                            AsyncCallback cb,
                                            object obj)
    {
        AsyncRequestState reqState =
                            new AsyncRequestState(ctx, cb, obj);
        AsyncRequest ar = new AsyncRequest(reqState);
        ThreadStart ts = new ThreadStart(ar.ProcessRequest);
        Thread t = new Thread(ts);
        t.Start();

        return reqState;
    }

    public void EndProcessRequest(IAsyncResult ar)
    {
        AsyncRequestState ars = ar as AsyncRequestState;
        if (ars != null)
        {
            // Some cleanup
        }
    }
}
class AsyncRequestState : IAsyncResult
{
    public AsyncRequestState(HttpContext ctx,
                                AsyncCallback cb,
                                object extraData)
    {
        _ctx = ctx;
        _cb = cb;
        _extraData = extraData;
    }

    internal HttpContext _ctx;
    internal AsyncCallback _cb;
    internal object _extraData;
    private bool _isCompleted = false;
    private ManualResetEvent _callCompleteEvent = null;

    internal void CompleteRequest()
    {
        _isCompleted = true;
        lock (this)
        {
            if (_callCompleteEvent != null)
                _callCompleteEvent.Set();
        }           
        if (_cb != null)
            _cb(this);
    }

    public object AsyncState
    { get { return (_extraData); } }
    public bool CompletedSynchronously
    { get { return (false); } }
    public bool IsCompleted
    { get { return (_isCompleted); } }
    public WaitHandle AsyncWaitHandle
    {
        get
        {
            lock (this)
            {
                if (_callCompleteEvent == null)
                    _callCompleteEvent = new ManualResetEvent(false);

                return _callCompleteEvent;
            }
        }
    }
}

class AsyncRequest
{
    private AsyncRequestState _asyncRequestState;

    public AsyncRequest(AsyncRequestState ars)
    {
        _asyncRequestState = ars;
    }

    public void ProcessRequest()
    {
        //calling webservice or executing sql command asynchronously
        AsyncIOOperationWithCallback(state =>
                                        {
                                            ((AsyncRequestState)state.Context)._ctx.Response.Write("Operation completed");
                                            _asyncRequestState.CompleteRequest();
                                        }, _asyncRequestState);

    }
}

person SalientBrain    schedule 25.09.2012    source источник
comment
как насчет использования сигнальных конструкций   -  person Prabhu Murthy    schedule 25.09.2012
comment
Что такое «неблокирующее ожидание»?   -  person Henk Holterman    schedule 25.09.2012
comment
Чего ты хочешь ждать?   -  person svick    schedule 25.09.2012


Ответы (2)


Подождите, по определению, это "блокировка". Вы можете подождать в другом потоке, но вы заблокируете этот поток. Если под «неблокирующим» вы подразумеваете неблокирующий пользовательский интерфейс, вы можете подождать в другом потоке и уведомить поток пользовательского интерфейса через event (который при необходимости обработает InvokeRequired/BeginInvoke).

Если это не то, о чем вы спрашиваете, пожалуйста, предоставьте более подробную информацию.

person Peter Ritchie    schedule 25.09.2012

Способ, которым вы обычно работаете с асинхронной операцией без блокировки потока, заключается в том, чтобы ваша асинхронная операция поддерживала обратный вызов. TPL действительно не делает здесь ничего волшебного; если базовые операции в какой-то момент не поддерживают какую-либо форму обратного вызова, в конечном итоге вы все равно застрянете с чем-то блокирующим. Классическая «начало/конец» Модель асинхронного программирования отлично справляется с этим требованием. .

Когда TPL действительно сияет, он обеспечивает лучшую поддержку обработки/агрегации исключений и позволяет использовать более сложные модели продолжения (такие как ContinueWhenAll или ContinueWhenAny). Существует также новая поддержка отмены, включая предотвращение последующего продолжения. Однако само продолжение на самом деле является не более чем обратным вызовом в более изящной и чистой упаковке.

person Dan Bryant    schedule 25.09.2012