0

スレッドをブロックせず、TPL ' ContinueWith なしで待機を実行するにはどうすればよいですか? 例のために。3.5で?TPL の 3.5 用の移植バージョン (RX チームによる) については知っていますが、そのために使用できるスレッド プリミティブを知りたいです (... TPL の背後にあるもの)。また、TPL での ContinueWith の代替手段は何ですか?

// このハンドラーは、非同期 IO 操作中にスレッドをブロックしますか?

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);

    }
}
4

2 に答える 2

0

スレッドをブロックせずに非同期操作を処理する通常の方法は、非同期操作でコールバックをサポートすることです。ここでは、TPL は魔法のようなことは何もしません。基礎となる操作がある時点で何らかの形式のコールバックをサポートしていない場合でも、最終的に何かをブロックすることになります。従来の「Begin/End」非同期プログラミング モデルは、この要件を完全にうまく処理します。

TPL が真価を発揮するのは、例外処理/集約のサポートを改善し、より複雑な継続モデル (ContinueWhenAll や ContinueWhenAny など) を許可することです。また、後続の継続の防止を含むキャンセルの新しいサポートもあります。ただし、継続自体は、実際には、より洗練されたクリーンなパッケージのコールバックにすぎません。

于 2012-09-25T15:21:59.070 に答える
0

定義上、待機は「ブロッキング」です。別のスレッドを待つことはできますが、そのスレッドをブロックすることになります。「非ブロッキング」がUI をブロックしないことを意味する場合は、別のスレッドで待機し、(必要に応じて/eventを処理する) を介して UI スレッドに通知できます。InvokeRequiredBeginInvoke

それがあなたが求めているものでない場合は、詳細を提供してください。

于 2012-09-25T14:55:38.887 に答える