重叠Socket.BeginSend / EndSend调用predictable行为 [英] Predictable behaviour of overlapping Socket.BeginSend / EndSend calls

查看:747
本文介绍了重叠Socket.BeginSend / EndSend调用predictable行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我说,我有一个类,它包装一个插座和(除其他外)进行异步发送数据。

Say, I have a class, that wraps a Socket and (in addition to other things) performs asynchronous sends of data.

我进行发送按以下方式(大大简称 - 没有错误处理等等等):

I perform the send in the following way (greatly abbreviated - no error handling etc etc):

private Socket _socket;

public void Write(byte[] data, Action callback)
{
    _socket.BeginSend(
        data, 0, data.Length, SocketFlags.None,
        new AsyncCallback(WriteMaybeDone),
        new { Data = data, SentSoFar = 0, Callback = callback}
    )
}

public void WriteMaybeDone(IAsyncResult ar)
{
    int bytesSent = _socket.EndSend(ar);
    var state = ar.AsyncState;
    state.SentSoFar += bytesSent;
    if (state.SentSoFar < state.Data.Length) {
        _socket.BeginSend(
            data, state.SentSoFar, State.Data.Length - state.SentSoFar,
            SocketFlags.None,
            new AsyncCallback(WriteMaybeDone), state
        );
    } else {
        if (state.Callback != null) {
            state.Callback();
        }
    }
}

下面我们保证,所有的数据发送,传递的回调函数被调用之前。

Here we ensure, that all data is sent, before the passed callback is called.

如何才能确保,即重叠的呼声写行为以predictable的方式?特别是,因为所有的数据被发送之前的回调,传递给BeginSend可能被调用。我需要确保,该数据,传递给调用写进到电线的的交错用数据,传递给随后的写入呼叫,被回调之前进行的第写被激发。

How can one ensure, that "overlapping" calls to Write behave in a predictable manner? Especially since the callback, that is passed to BeginSend might be called before all data is sent. I need to ensure, that the data, that is passed to a call to Write goes to the wire not interleaved with data, that is passed to subsequent Write calls, that are made before the callback for the first Write is fired.

我不得不.NET 3.5

I am constrained to .NET 3.5

推荐答案

只有启动后,previous完成了一个发送操作。你可以排队的待发送的数据,或者使用的信令机制(如 AsyncSemaphore TaskCompletionSource ),通知下一个写在previous完成。

Only start the next send operation after the previous completed. You could enqueue the data to be sent, or use a signaling mechanism (like AsyncSemaphore or TaskCompletionSource) to notify the next write that the previous is done.

在换句话说,使用一个生产者 - 消费者设计图案。生产者是要写入的操作。单个消费者线程或异步的工作流程,做物理写入一个接一个。

In other words, use a producer-consumer design pattern. The producers are the operations that want to write. The single consumer is a thread or async workflow that does the physical writes one after the other.

这篇关于重叠Socket.BeginSend / EndSend调用predictable行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆