Ejemplo n.º 1
0
        /// <summary>
        /// This method is based upon increasing the MaxInfoFrames in the MSTP.
        /// In Bacnet/IP this will have bad effect due to the retries
        /// </summary>
        public void DownloadFileByAsync(BacnetClient comm, BacnetAddress adr, BacnetObjectId object_id, string filename, Action <int> progress_action)
        {
            Cancel = false;

            //open file
            System.IO.FileStream fs = null;
            try
            {
                fs = System.IO.File.OpenWrite(filename);
            }
            catch (Exception ex)
            {
                throw new System.IO.IOException("Couldn't open file", ex);
            }

            uint max_count = (uint)comm.GetFileBufferMaxSize();

            BacnetAsyncResult[] transfers = new BacnetAsyncResult[50];
            byte old_max_info_frames      = comm.Transport.MaxInfoFrames;

            comm.Transport.MaxInfoFrames = 50;      //increase max_info_frames so that we can occupy line more. This might be against 'standard'

            try
            {
                int  position = 0;
                bool eof      = false;

                while (!eof && !Cancel)
                {
                    //start many async transfers
                    for (int i = 0; i < transfers.Length; i++)
                    {
                        transfers[i] = (BacnetAsyncResult)comm.BeginReadFileRequest(adr, object_id, position + i * (int)max_count, max_count, false);
                    }

                    //wait for all transfers to finish
                    int current = 0;
                    int retries = comm.Retries;
                    while (current < transfers.Length)
                    {
                        if (!transfers[current].WaitForDone(comm.Timeout))
                        {
                            if (--retries > 0)
                            {
                                transfers[current].Resend();
                                continue;
                            }
                            else
                            {
                                throw new System.IO.IOException("Couldn't read file");
                            }
                        }
                        retries = comm.Retries;

                        uint      count;
                        byte[]    file_buffer;
                        int       file_buffer_offset;
                        Exception ex;
                        comm.EndReadFileRequest(transfers[current], out count, out position, out eof, out file_buffer, out file_buffer_offset, out ex);
                        transfers[current] = null;
                        if (ex != null)
                        {
                            throw ex;
                        }

                        if (count > 0)
                        {
                            //write to file
                            fs.Position = position;
                            fs.Write(file_buffer, file_buffer_offset, (int)count);
                            position += (int)count;
                            if (progress_action != null)
                            {
                                progress_action(position);
                            }
                        }
                        current++;
                    }
                }
            }
            finally
            {
                fs.Close();
                comm.Transport.MaxInfoFrames = old_max_info_frames;
            }
        }