Forum Discussion

0ylanmorisson's avatar
0ylanmorisson
Explorer | Level 3
8 years ago

Upload sometimes needs pressing enter to proceed.

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...");
        }

 

  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff
    If your program is waiting for keyboard input, that sounds more like something to do with its use of Console, and not the Dropbox API. The Dropbox API is just a programmatic interface, so it doesn't require manual user input.

    I recommend using the debugger to see exactly where execution is pausing.

    Also, I noticed that you're calling RunChunkedUpload, but the code you shared doesn't have a definition for that. It only shows ChunkedUpload. Are you maybe running a different method than you're expecting?
    • 0ylanmorisson's avatar
      0ylanmorisson
      Explorer | Level 3

      No, I didn't paste RunChunkedUpload() here because I thought it was trivial.

      Here is the code:

              private async Task RunChunkedUpload(DropboxClient client)
              {
                  Console.WriteLine("\nInput local file path: ");
                  var srcfile = Console.ReadLine();
      
                  Console.WriteLine("\nInput dropbox path:");
                  var dstfile = Console.ReadLine();
      
                  await GetCurrentAccount(client);
                  await ChunkedUpload(client, srcfile, dstfile);
              }

      And no, my program doesn't need waiting for keyboard response. Once given the local file name and remote file name, it's supposed to start uploading and continuously upload chunk by chunk .

       

      So it is really wierd that I have to sit in front of the computer and monitor the uploading process and press enter to make the uploading process continue if it suspends from time to time ( because this problem doesn't happen every time).

      • Greg-DB's avatar
        Greg-DB
        Icon for Dropbox Staff rankDropbox Staff
        Thanks! Calls to Console.ReadLine like that would cause the requirement of console input like that, but based on your output it doesn't look like these particular instances of Console.ReadLine are the cause. Do you have Console.ReadLine anywhere else in your code?

        Also, I do recommend using the debugger to step into your app while it's executing to see exactly where/when this happening.