My uploading code seems working. But the uploading progress often suspends and it only continues after I press enter.
The progress display is like this:
Authorizing...
Authorize OK!
//Sometimes the program suspends here for like 10 minutes. I have to press enter to make it display the following.
Start uploading...
Uploaded 1: 1000000b of total 12896545b.
Uploaded 2: 2000000b of total 12896545b.
...
//And sometimes I have to press enter line by line to make Console.WriteLine() work.
...
Uploaded 12: 12896545b of total 12896545b.
Upload OK!
Is this an API problem or Console.WriteLine() problem? Why is this happening?
private static void Main(string[] args)
{
var instance = new Program();
var task = Task.Run((Func<Task<int>>)instance.Run);
try
{
task.Wait();
}
catch (Exception e)
{
Console.WriteLine("Error {0}.. Exiting.. \n", e.Message);
Environment.Exit(0);
}
}
private async Task<int> Run()
{
DropboxCertHelper.InitializeCertPinning();
var accessToken = await this.GetAccessToken();
if (string.IsNullOrEmpty(accessToken))
{
return 1;
}
var httpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 })
{
Timeout = TimeSpan.FromMinutes(20)
};
try
{
var config = new DropboxClientConfig("SimpleTestApp")
{
HttpClient = httpClient
};
var client = new DropboxClient(accessToken, config);
await RunChunkedUpload(client);
}
catch (HttpException e)
{
Console.WriteLine("Exception reported from RPC layer");
Console.WriteLine(" Status code: {0}", e.StatusCode);
Console.WriteLine(" Message : {0}", e.Message);
if (e.RequestUri != null)
{
Console.WriteLine(" Request uri: {0}", e.RequestUri);
}
Environment.Exit(0);
}
return 0;
}
private async Task ChunkedUpload(DropboxClient client, string srcfile, string dstfile)
{
if (!File.Exists(srcfile))
{
Environment.Exit(0);
}
// Chunk size is 1024 * 1024 = 1048576B.
const int chunkSize = 1000000;
long currentPosition = 0;
FileStream fs = new FileStream(srcfile, FileMode.Open);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();
using (var stream = new MemoryStream(data))
{
int numChunks = (int)Math.Ceiling((double)stream.Length / chunkSize);
byte[] buffer = new byte[chunkSize];
string sessionId = null;
bool isUploaded = true;
bool isResume = false;
var byteRead=0;
var idx = 0;
string logpath = this.GetType().Assembly.Location + ".log.txt"; // + @\
if (File.Exists(logpath))
{
StreamReader objReader = new StreamReader(logpath);
isResume = true;
string line;
int nline = 0;
while ((line = objReader.ReadLine()) != null)
{
if ( nline ==0)
{
sessionId = line;
nline++;
continue;
}
if ( nline == 1)
{
currentPosition = long.Parse(line);
nline++;
continue;
}
if (nline == 2)
{
idx = int.Parse(line);
nline++;
continue;
}
}
Console.WriteLine("\nReloading log.. SessionID:{0}. Offset:{1}.\n", sessionId, currentPosition);
objReader.Close();
File.Delete(logpath);
}
do
{
if (isUploaded)
{
byteRead = stream.Read(buffer, 0, chunkSize);
}
if (isResume)
{
stream.Seek(currentPosition, SeekOrigin.Begin);
byteRead = stream.Read(buffer, 0, chunkSize);
}
try
{
using (MemoryStream memStream = new MemoryStream(buffer, 0, byteRead))
{
if (idx == 0)
{
var result = await client.Files.UploadSessionStartAsync(body: memStream);
sessionId = result.SessionId;
isUploaded = true;
isResume = false;
Console.WriteLine("\nStart uploading file {0} to Dropbox path: {1}.\n", srcfile, dstfile );
}
else
{
UploadSessionCursor cursor = new UploadSessionCursor(sessionId, (ulong)currentPosition);
if (idx == numChunks - 1)
{
await client.Files.UploadSessionFinishAsync(cursor, new CommitInfo(dstfile), memStream);
isUploaded = true;
isResume = false;
}
else
{
await client.Files.UploadSessionAppendV2Async(cursor, body: memStream);
isUploaded = true;
isResume = false;
}
FileStream log = new FileStream(logpath, FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(log);
sw.WriteLine(sessionId.ToString());
sw.WriteLine(cursor.Offset.ToString());
sw.WriteLine(idx.ToString());
sw.Close();
fs.Close();
Console.WriteLine("Uploaded {0}: {1}kb of total {2}kb. SessionID: {3}.", idx, cursor.Offset.ToString(), (int)Math.Ceiling((double)stream.Length), sessionId);
}
}
}
catch (ApiException<UploadSessionLookupError> e)
{
if (e.ErrorResponse.IsIncorrectOffset)
{
currentPosition = int.Parse(e.ErrorResponse.AsIncorrectOffset.Value.CorrectOffset.ToString());
StreamWriter sw = new StreamWriter(logpath);
sw.WriteLine(sessionId.ToString());
sw.WriteLine(e.ErrorResponse.AsIncorrectOffset.Value.CorrectOffset.ToString());
sw.WriteLine(idx.ToString());
sw.Close();
Console.WriteLine("\nError uploading:{0}. SessionID: {1}. CorrectOffset:{2}. Reuploading..\n", e.Message, sessionId, e.ErrorResponse.AsIncorrectOffset.Value.CorrectOffset.ToString());
currentPosition = int.Parse(e.ErrorResponse.AsIncorrectOffset.Value.CorrectOffset.ToString());
isUploaded = false;
continue;
}
}
catch (Exception e)
{
idx--;
isUploaded = false;
Console.WriteLine("\nError uploading:{0}. SessionID: {1}. Exiting...\n", e.Message, sessionId, sessionId );
Environment.Exit(0);
}
idx++;
currentPosition = currentPosition + byteRead;
} while (idx < numChunks);
File.Delete(logpath);
}
Console.WriteLine("\nUpload OK! Exiting...");
}