Estoy tratando de transferir un archivo a través de un IHttpHandler, el código es bastante simple. Sin embargo, cuando comienzo una sola transferencia, usa aproximadamente el 20% de la CPU. Si tuviera que escalar esto a 20 transferencias simultáneas, la CPU es muy alta. ¿Hay alguna manera mejor de que pueda hacer esto para mantener baja la CPU? el código del cliente solo envía fragmentos del archivo de 64 KB a la vez.Transferencia de archivos comiendo una gran cantidad de CPU
public void ProcessRequest(HttpContext context)
{
if (context.Request.Params["secretKey"] == null)
{
}
else
{
accessCode = context.Request.Params["secretKey"].ToString();
}
if (accessCode == "test")
{
string fileName = context.Request.Params["fileName"].ToString();
byte[] buffer = Convert.FromBase64String(context.Request.Form["data"]);
string fileGuid = context.Request.Params["smGuid"].ToString();
string user = context.Request.Params["user"].ToString();
SaveFile(fileName, buffer, user);
}
}
public void SaveFile(string fileName, byte[] buffer, string user)
{
string DirPath = @"E:\Filestorage\" + user + @"\";
if (!Directory.Exists(DirPath))
{
Directory.CreateDirectory(DirPath);
}
string FilePath = @"E:\Filestorage\" + user + @"\" + fileName;
FileStream writer = new FileStream(FilePath, File.Exists(FilePath) ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
writer.Write(buffer, 0, buffer.Length);
writer.Close();
}
Aquí está mi código de cliente:
//Set filename from object
string FileName;
FileName = System.IO.Path.GetFileName(pubAttFullPath.ToString());
//Open file
string file = System.IO.Path.GetFileName(pubAttFullPath.ToString());
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
//Chunk size that will be sent to Server
int chunkSize = 65536;
// Unique file name
string fileName = smGuid.ToString() + "_" + FileName;
int totalChunks = (int)Math.Ceiling((double)fileStream.Length/chunkSize);
// Loop through the whole stream and send it chunk by chunk;
for (int i = 0; i < totalChunks; i++)
{
bool doRecieve = true;
int cpt = 0;
do
{
int startIndex = i * chunkSize;
int endIndex = (int)(startIndex + chunkSize > fileStream.Length ? fileStream.Length : startIndex + chunkSize);
int length = endIndex - startIndex;
byte[] bytes = new byte[length];
fileStream.Read(bytes, 0, bytes.Length);
//Request url, Method=post Length and data.
string requestURL = "http://localhost:16935/Transfer.doit";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
// Wait 5 min for answer before close connection.
request.Timeout = 300000;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Chunk(buffer) is converted to Base64 string that will be convert to Bytes on the handler.
string requestParameters = @"fileName=" + fileName + @"&secretKey=test" + @"¤tChunk=" + i + @"&totalChunks=" + totalChunks + @"&smGuid=" + smGuid
+ "&user=" + userSID.ToString() +
"&data=" + HttpUtility.UrlEncode(Convert.ToBase64String(bytes));
// finally whole request will be converted to bytes that will be transferred to HttpHandler
byte[] byteData = Encoding.UTF8.GetBytes(requestParameters);
request.ContentLength = byteData.Length;
try
{
Stream writer = request.GetRequestStream();
writer.Write(byteData, 0, byteData.Length);
writer.Close();
// here we will receive the response from HttpHandler
StreamReader stIn = new StreamReader(request.GetResponse().GetResponseStream());
string strResponse = stIn.ReadToEnd();
stIn.Close();
doRecieve = true;
}
catch (WebException webException)
{
if (webException.Status == WebExceptionStatus.ConnectFailure ||
webException.Status == WebExceptionStatus.ConnectionClosed ||
webException.Status == WebExceptionStatus.ReceiveFailure ||
webException.Status == WebExceptionStatus.SendFailure ||
webException.Status == WebExceptionStatus.Timeout)
{
Thread.Sleep(5000);
doRecieve = false;
cpt++;
}
else {
// if the exception is not those ones then get out
doRecieve = true;
}
}
catch (Exception e)
{
doRecieve = true;
}
}
// will try to send 3 times the current chunk before quitting
// can't try it so try it and give me the feedback
while(doRecieve == false && cpt < 3);
}
¿En qué basa sus estadísticas de uso de CPU? – CodingGorilla
Iniciando una transferencia y viendo perfmon. Yo soy el único que lo usa. –
¿Está esto en una máquina de desarrollo o en un servidor real? – CodingGorilla