When experimenting some more with these two values I found that the higher the TransferBufferSize, the faster my transfer goes. When I pumped it up to 500 KB, my speed skyrocketed from avg ~40KB/sec to ~500KB/sec! Also, the BytesTransferred event seems to fire based on the TransferBufferSize instead of the TransferNotifyInterval. If I change only the TransferNotifyInterval, I see no change in the way the status bar updates, but if I change the TransferBufferSize then it changes the update speed (as well as the transfer speed):
ftpConn.TransferNotifyInterval = 512;
ftpConn.TransferBufferSize = 512000;
The BytesTransferred event only fired every 500 KB instead of every 1/2 KB but at speeds of 500KB/sec. 512000 seemed to be the optimal setting; changing to 1 MB TransferBufferSize didn't increase the speed any more.
I watched the file grow on the destination FTP server and it did appear to transfer much faster with a higher TransferBufferSize.
When I swapped the two values for TransferNotifyInterval and TransferBufferSize:
ftpConn.TransferNotifyInterval = 512000;
ftpConn.TransferBufferSize = 512;
It still updated only every 500 KB, but the speed dropped to 66 KB/sec.
I want to set the TransferBufferSize higher to get the higher speed, but I don't want the update to be so infrequent. Anyone have any ideas on how to accomplish this?
Looking at ftpClient.PutBinary(), I'm wondering if the reason that TransferNotifyInterval doesn't work for intervals less than TransferBufferSize because it loads the entire buffer size first and only then has a chance to fire the event. This might have to be rewritten as an asynchronous BinaryWrite using the BeginWrite() method and have event handlers to get notifications.
// get an output stream
output = new BinaryWriter(data.DataStream);
while ((count = input.Read(buf, 0, buf.Length)) > 0 && !cancelTransfer)
{
output.Write(buf, 0, count);
size += count;
monitorCount += count;
KeepAlive();
if (BytesTransferred != null && monitorCount > monitorInterval)
{
BytesTransferred(this, new BytesTransferredEventArgs(remoteFile, size));
monitorCount = 0;
}
}