Changes in Effective Data-Transfer Rate in Mobilized .NET Applications


Challenge

Detect changes in effective data-transfer rate in a mobilized .NET* application. If we can detect changes in the effective data rate between two endpoints, then users can subscribe to high and low thresholds, and we can notify them when these thresholds are crossed. The two most likely uses of this information are as follows:

 

  • An application has a large transfer that it does not want to begin until the effective data rate to its target endpoint rises above a certain threshold.
  • An application that is currently transferring data wishes to be notified when the effective data rate of the transfer drops below a certain threshold.

 

Notice that for the first scenario, non-application data must be used to measure the data rate, because the user wants the effective data rate in order to begin a transfer. In the second scenario, however, the application-specific data can be used to measure the data rate. Therefore, our discussion needs to answer the question in two scenarios: when a transfer is already taking place, and when a transfer is pending.


Solution

Use the Send() and Receive() methods on the extended Socket() class illustrated in the companion item to this one (“How to Determine Effective Data-Transfer Rate in Mobilized .NET Applications”) to track the data rate. Let's provide delegates and threshold subscription methods:

//The threshold event delegate

public delegate void DataRateThresholdEventHandler(

    object sender, 

    DataRateThresholdEventArgs e);


public DataRateAwareSocket: Socket

{

    //....

    protected double m_dSendLowThreshold;

/ KB/sec

    protected event DataRateThresholdEventHandler

        SendDataRateLowThresholdEvent;

    //....

   
    //Allow them to subscribe to the event and specify a threshold

    public void SubscribeSendRateBelowThreshold(

        double dKBytesPerSecond, 

        DataRateThresholdEventHandler eventHandler)

    {

        this.SendDataRateLowThresholdEvent += eventHandler;

        this.m_dSendLowThreshold = dKBytesPerSecond ;

    }  
  
}

 

We then begin our own thread to use the SampleSendRate() method we defined above, compare the rate with the threshold, and notify the user when the data rate crosses the threshold:

//Don't call on the same thread that is sending

protected void SampleAndEvaluateSendRate()

{
        
    while (m_bAlive)

    {

        //sample the send rate
        double rate = this.SampleSendRate(

        new TimeSpan( 0,0,0,0, this.m_iSampleLength ) );


        //if it is below the send threshold, raise an event

        if ( rate < this.m_dSendLowThreshold )

        {

            if ( this.SendDataRateLowThresholdEvent != null )

        {

            SendDataRateLowThresholdEvent( this, 

                new DataRateThresholdEventArgs( rate ) );

            }

        }

        Thread.Sleep(this.m_iPollingInterval);

    }

}

 

If we need notification that the data rate has risen above a threshold before we transfer data, we have to be a little more creative. Because we logically have to transfer some data in order to calculate a data rate greater than 0, we have two choices: transfer non-application data or transfer application data.

A good choice for non-application data is ICMP (ping) data. To do this, we modify our SampleSendRate() method to use either our custom Socket ICMP functionality, or the WMI Win32_PingStatus class. Another option would be to inject traffic measuring data into the sockets that have already been established, but that would require the receiver to have the ability to filter out and discard non-application traffic.

However, if we have the option to use application data in our SampleSendRate() method, notifying subscribers that the data rate has risen above a threshold simply involves reversing the logic of the SampleAndEvaluateSendRate() method.

This item is part of a series of items that present sample implementations to obtain network-connection information using the classes found in the .NET Framework:

 

 


Source

Mobilized .NET* Applications

 


For more complete information about compiler optimizations, see our Optimization Notice.
Categories: