public void ProcessEndRequest(DateTime lastWriteTime)
        {
            UploadFileEndResponse endResponse = new UploadFileEndResponse()
            {
                UploadSessionID = UploadSessionID,
                RequestID       = LastRequestID
            };

            if (!_isRunning)
            {
                endResponse.Success = false;
                endResponse.Message = "the uploading is not running";
            }
            else
            {
                try
                {
                    _fileStream.Close();
                    File.SetLastWriteTime(SavePath, lastWriteTime);
                    endResponse.Success = true;
                }
                catch (Exception ex)
                {
                    endResponse.Success = false;
                    endResponse.Message = ex.Message;
                }
            }

            _tcpServer.SendModelMessage(ClientID, endResponse);
            _isRunning = false;
            Finished?.Invoke();
        }
        private void UploadProc(object obj)
        {
            TcpModelClient uploadClient = new TcpModelClient(false, (int)MessageHeader.Model, JsonModelMessageConvert.Default);

            try
            {
                uploadClient.Connect(ServerIPAddress, ServerPort);
                SetProgress(0, 0);
                string filePath = (string)obj;
                //1.upload file request
                AddLog("Request to upload file...");
                FileInfo fi = new FileInfo(filePath);
                UploadFileBeginRequest uploadRequestMsg = new UploadFileBeginRequest()
                {
                    FileName = Path.GetFileName(filePath),
                    FileSize = fi.Length
                };
                UploadFileBeginResponse uploadReponseMsg = uploadClient.QueryAsync <UploadFileBeginResponse>(uploadRequestMsg).Result;

                if (!uploadReponseMsg.AllowUpload)
                {
                    throw new Exception("upload failed:" + uploadReponseMsg.Message);
                }
                AddLog("can upload file");
                //2.upload file data
                UploadFileData uploadData = new UploadFileData()
                {
                    UploadSessionID = uploadReponseMsg.UploadSessionID
                };
                FileStream fs        = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                byte[]     buffer    = new byte[10 * 1024];
                long       totalSend = 0;
                int        lastTick  = Environment.TickCount;
                int        startTick = Environment.TickCount;
                while (true)
                {
                    //process cancellation
                    if (_cancelTokenSource.IsCancellationRequested)
                    {
                        fs.Close();
                        UploadFileCancelRequest cancelRequest = new UploadFileCancelRequest()
                        {
                            UploadSessionID = uploadReponseMsg.UploadSessionID
                        };
                        UploadFileCancelResponse cancelResponse = uploadClient.QueryAsync <UploadFileCancelResponse>(cancelRequest, int.MaxValue).Result;
                        AddLog("the uploading is cancelled");
                        return;
                    }
                    int readLen = fs.Read(buffer, 0, buffer.Length);
                    if (readLen <= 0)
                    {
                        double percent = (double)totalSend * 100.0 / (double)fi.Length;
                        double speed   = (double)totalSend * 1000.0 / ((double)(Environment.TickCount - startTick) * 1024.0 * 1024.0);
                        SetProgress(percent, speed);
                        fs.Close();
                        break;
                    }
                    totalSend += readLen;
                    int curTick = Environment.TickCount;
                    if (curTick - lastTick >= 300)
                    {
                        double percent = (double)totalSend * 100.0 / (double)fi.Length;
                        double speed   = (double)totalSend * 1000.0 / ((double)(curTick - startTick) * 1024.0 * 1024.0);
                        SetProgress(percent, speed);
                        lastTick = Environment.TickCount;
                    }
                    GeneralMessage generalMessage = _tcpClient.ConvertToGeneralMessage(uploadData);
                    generalMessage.Payload = new ArraySegment <byte>(buffer, 0, readLen);
                    uploadClient.SendMessage(generalMessage.Serialize());
                }

                //3.finish upload
                UploadFileEndRequest endRequest = new UploadFileEndRequest
                {
                    ID              = Guid.NewGuid(),
                    LastWriteTime   = fi.LastWriteTime,
                    UploadSessionID = uploadReponseMsg.UploadSessionID
                };
                UploadFileEndResponse endResponse = uploadClient.QueryAsync <UploadFileEndResponse>(endRequest, int.MaxValue).Result;
                if (endResponse.Success)
                {
                    SetProgress(100, -1);
                    AddLog("upload finished");
                }
                else
                {
                    AddLog("upload failed:" + endResponse.Message);
                }
            }
            finally
            {
                uploadClient.Close();
            }
        }