Thread's response time is very much(not usual) - c#

i want to download a file in C# using a thread in a windows form app,thread works fine at first(for 5 seconds) but suddenly it leaves it work and not respond sometimes for about 10 seconds then it returns a second and then not respond
i am using a class for downloading file
here is the code:
class DownloadFile
{
#region Fields
static Double totalsize;
Double received;
int PartNum;
long start, end;
string savepath;
HttpWebRequest request;
Stream stream;
#endregion
#region Constructors
public DownloadFile() { totalsize = 1; received = 0; }
public DownloadFile(long s, long e, string PATH, HttpWebRequest REQUEST, int Partnumber)
{
totalsize = 1;
PartNum = Partnumber;
received = 0;
start = s;
request = REQUEST;
end = e;
savepath = PATH;
}
#endregion
#region Methods
public void DownLoad()
{
int bytesRead = 0;
byte[] buffer = new byte[1024];
FileStream fstr = new FileStream(savepath + "Part_" + PartNum + Path.GetExtension(Request.RequestUri.ToString()), FileMode.Create, FileAccess.Write);
HttpWebResponse response;
this.request.AddRange(start, end);
response = (HttpWebResponse)this.Request.GetResponse();
stream = response.GetResponseStream();
totalsize = this.end;
bytesRead = stream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
received += bytesRead;
fstr.Write(buffer, 0, bytesRead);
bytesRead = stream.Read(buffer, 0, buffer.Length);
}
fstr.Close();
stream.Close();
}
public void AppendFiles()
{
}
#endregion
#region properties
public long End
{
get { return end; }
set { end = value; }
}
public long Start
{
get { return start; }
set { start = value; }
}
public Double Received
{
get { return received; }
}
public Double Totalsize
{
get { return totalsize; }
}
public HttpWebRequest Request
{
get { return request; }
set { request = value; }
}
public string SavePath
{
get { return savepath; }
set { savepath = value; }
}
#endregion
}
and here is where thread starts:
Class Program{
List<DownloadFile> DownLoadList = new List<DownloadFile>();
public void DownloadMethod()
{
for (int i = 0; i < DownLoadList.Count; i++)
{
new Thread(new ThreadStart(DownLoadList.ElementAt(i).DownLoad)).Start();
}
}
}
and also i have a timer that updates the download form(progressBar and labels)

Related

Filestream.readtimeout: invalid operation exception

I want to download file (.PDF as an example) using File stream. Here is a contrived example:
public ActionResult GetPDF()
{
ActionResult ar = null;
FileStream fs = null;
try
{
fs = System.IO.File.OpenRead(filename);
var bytes = new byte[fs.Length];
var x = fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
abcd fr = new abcd(fs, "application/pdf");
}
catch(Exception)
{
}
return ar;
}
public class CheckedFileStreamResult : FileStreamResult
{
public bool DownloadCompleted { get; set; }
public CheckedFileStreamResult(FileStream stream, string contentType)
: base(stream, contentType)
{
DownloadCompleted = false;
}
protected override void WriteFile(HttpResponseBase response)
{
var outputStream = response.OutputStream;
response.BufferOutput = false;
using (FileStream)
{
var buffer = new byte[_bufferSize];
var count = FileStream.Read(buffer, 0, _bufferSize);
while (count != 0 && response.IsClientConnected)
{
outputStream.Write(buffer, 0, count);
count = FileStream.Read(buffer, 0, _bufferSize);
}
DownloadCompleted = response.IsClientConnected;
}
}
private const int _bufferSize = 0x1000;
}
public class abcd : CheckedFileStreamResult
{
public abcd(FileStream stream, string contentType) : base(stream, contentType)
{
DownloadCompleted = false;
}
public void Write(HttpResponseBase response)
{
WriteFile(response);
}
}
I always get count with value 0. Invalid Operation Exception is thrown here:
var count = FileStream.Read(buffer, 0, _bufferSize);
Please guide me how can I proceed. I want to know whether the file was downloaded successfully.

Why isn't it possible to read my byteBuffer String out?(c#)

I wrote a basic server client program with c# and Unity to create my own network. During the process I wrote a byteBuffer to send data over the network. Everything works, but to send or receive the String. (I can send Integers and other dataforms succesfully).
My DLL file:
public class ByteBuffer : IDisposable
{
private List<byte> Buff;
private byte[] readBuff;
private int readpos;
private bool buffUpdated;
private bool disposedValue;
#region "Helpers"
public ByteBuffer()
{
this.buffUpdated = false;
this.disposedValue = false;
this.Buff = new List<byte>();
this.readpos = 0;
}
public long GetReadPos() =>
((long)this.readpos);
public byte[] ToArray() =>
this.Buff.ToArray();
public int Count() =>
this.Buff.Count;
public int Length() =>
(this.Count() - this.readpos);
public void Clear()
{
this.Buff.Clear();
this.readpos = 0;
}
#endregion
#region"Write Data"
public void WriteByte(byte Inputs)
{
Buff.Add(Inputs);
buffUpdated = true;
}
public void WriteBytes(byte[] Input)
{
this.Buff.AddRange(Input);
this.buffUpdated = true;
}
public void WriteInteger(int Input)
{
this.Buff.AddRange(BitConverter.GetBytes(Input));
this.buffUpdated = true;
}
public void WriteString(string Input)
{
this.Buff.AddRange(BitConverter.GetBytes(Input.Length));
this.Buff.AddRange(Encoding.ASCII.GetBytes(Input));
this.buffUpdated = true;
}
#endregion
#region "read Data"
public string ReadString(bool Peek = true)
{
int count = this.ReadInteger(true);
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
string str = Encoding.ASCII.GetString(this.readBuff, this.readpos, count);
if ((Peek & (this.Buff.Count > this.readpos)) && (str.Length > 0))
{
this.readpos += count;
}
return str;
}
public byte ReadByte(bool Peek = true)
{
if (Buff.Count > readpos)
{
if (buffUpdated)
{
readBuff = Buff.ToArray();
buffUpdated = false;
}
byte ret = readBuff[readpos];
if (Peek & Buff.Count > readpos)
{
readpos += 1;
}
return ret;
}
else
{
throw new Exception("Byte Buffer is past its Limit!");
}
}
public byte[] ReadBytes(int Length, bool Peek = true)
{
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
byte[] buffer = this.Buff.GetRange(this.readpos, Length).ToArray();
if (Peek)
{
this.readpos += Length;
}
return buffer;
}
public int ReadInteger(bool peek = true)
{
if (this.Buff.Count <= this.readpos)
{
throw new Exception("Byte Buffer Past Limit!");
}
if (this.buffUpdated)
{
this.readBuff = this.Buff.ToArray();
this.buffUpdated = false;
}
int num = BitConverter.ToInt32(this.readBuff, this.readpos);
if (peek & (this.Buff.Count > this.readpos))
{
this.readpos += 4;
}
return num;
}
#endregion
//IDisposable
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if(disposing)
{
this.Buff.Clear();
}
this.readpos = 0;
}
this.disposedValue = true;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
My SendData Class:
class ServerSendData{
public static ServerSendData instance = new ServerSendData();
public void SendDataToClient(int index, byte[] data)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
Network.Clients[index].myStream.BeginWrite(buffer.ToArray(), 0, buffer.ToArray().Length, null, null);
buffer = null;
}
public void SendWelcomeMessage(int index)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteInteger(1); //paket nummer 1
buffer.WriteByte(2);
buffer.WriteString("A");
SendDataToClient(index, buffer.ToArray());
}
}
My HandleData Class:
public class ClientHandleData: MonoBehaviour{
public void HandleData(byte[]data)
{
int packetNum;
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
packetNum = buffer.ReadInteger();
buffer = null;
if (packetNum == 0)
{
return;
}
else
{
HandleMessages(packetNum, data);
}
}
public void HandleMessages(int packetNum, byte[] data)
{
switch (packetNum)
{
case 1:
HandleWelcomeMessage(data);
break;
}
}
public void HandleWelcomeMessage(byte[] data)
{
ByteBuffer.ByteBuffer buffer = new ByteBuffer.ByteBuffer();
buffer.WriteBytes(data);
Debug.Log("Test");
int nummer = buffer.ReadInteger();
Debug.Log("Test1: "+nummer);
byte bt = buffer.ReadByte();
Debug.Log("Test2: " +bt);
message = buffer.ReadString();
Debug.Log("Test3");
Debug.Log(nummer);
Debug.Log(message);
Debug.Log(bt);
buffer = null;
}
}
My Log result looks like:
Test
Test1: 1
Test2: 2
Working with Unity 2018.2.11f1 personal 64 bit

Background work completed never fired

After background process DoWork() the control is exit from the block but it never fire a RunWorkerCompleted() and one more thing is isBusy is still true
Please help me
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
sendFile.Send();
}));
This is my FileReadWrite.cs file
Whenever I used this file in xaml class file it worked but there I am using Dispatcher in DispatcherObject class from WindowBase.dll but in another .cs file I can't use that DispatcherObject class that's why I am using Dispatcher.CurrentDispatcher.Invoke()
public class FileReadWrite
{
public int SourceId;
public int DestinationId;
public string FileName;
public WebSocket WebSocket;
public int SplitSize;
public int ReferenceId;
BinaryWriter _binaryWriter;
public int _totalsequence = 0;
public int progvalue;
public static double totallength;
public static double calculate, sendlen;
public static int post;
public double calc, count, len, sentsize;
public static int FileSendCount = 0;
public static List<byte[]> FileList = new List<byte[]>();
public BackgroundWorker _worker = new BackgroundWorker();
public FileReadWrite()
{
_worker.DoWork += _worker_DoWork;
_worker.RunWorkerCompleted += _worker_RunWorkerCompleted;
}
void _worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
FileCloseMessage fileclosemsg = new FileCloseMessage();
fileclosemsg.Source = SourceId;
fileclosemsg.Destination = DestinationId;
fileclosemsg.Date = DateTime.Now;
fileclosemsg.Sequenceno = 0;
fileclosemsg.totalsequence = _totalsequence;
byte[] bytess = fileclosemsg.GetBytes();
FileList.Add(bytess);
}
void _worker_DoWork(object sender, DoWorkEventArgs e)
{
using (BinaryReader b = new BinaryReader(File.Open(FileName, FileMode.Open)))
{
int pos = 0;
int length = (int)b.BaseStream.Length;
totallength = Convert.ToDouble(length);
byte[] bytes = new byte[SplitSize];
while (pos < length)
{
if (pos + SplitSize > length)
{
bytes = new byte[length - pos];
}
len = Convert.ToDouble(length);
bytes = b.ReadBytes(bytes.Length);
FileContentMesssage fileContentMesssage = new FileContentMesssage();
fileContentMesssage.Content = bytes;
fileContentMesssage.ReferenceId = ReferenceId;
pos += SplitSize;
fileContentMesssage.SequenceNo = pos / SplitSize;
_totalsequence++;
byte[] filebytes = fileContentMesssage.GetBytes();
FileList.Add(filebytes);
}
}
}
public async void Send()
{
_worker.RunWorkerAsync();
}
public void FileReceive(byte[] bytes)
{
try
{
if (_binaryWriter != null)
_binaryWriter.Write(bytes);
}
catch (Exception ex)
{
}
}
public string FileCreate()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string filename = Path.GetFileName(FileName);
string fullfilename = string.Format("{0}{1}", path, filename);
_binaryWriter = new BinaryWriter(File.Open(fullfilename, FileMode.Create));
return (fullfilename);
}
public void FileClose()
{
_binaryWriter.Close();
}
public byte[] FileSend()
{
byte[] bytess = FileList[FileSendCount];
FileSendCount++;
return (bytess);
}
public void FileClosed()
{
FileSendCount = 0;
FileList.Clear();
post = 0;
sendlen = 0;
calculate = 0;
totallength = 0;
_totalsequence = 0;
}
}

UWP with UDP StreamWriter in OSC format

I have following class take care the udp Sending
public static async Task SendStringUdpAsync(HostName remoteHost,
string remotePort, string message)
{
using (var socket = new DatagramSocket())
{
var stream = (await socket.GetOutputStreamAsync(
remoteHost, remotePort)).AsStreamForWrite();
using (var writer = new StreamWriter(stream))
{
await writer.WriteLineAsync(message.ToString());
await writer.FlushAsync();
}
}
}
But instead send a string, I want to send a custom class in udp
public class OSCString : IOSCValue<string>
{
static int PaddingLength = 4;
public string Contents { get; }
public char TypeTag { get { return 's'; }}
public byte[] Bytes { get; }
public OSCString(string contents)
{
Contents = contents;
Bytes = GetBytes();
}
public byte[] GetBytes()
{
byte[] bytes = new byte[GetByteLength()];
Encoding.ASCII.GetBytes(Contents, 0, Contents.Length, bytes, 0);
return bytes;
}
public int GetByteLength()
{
return GetPaddedLength(Contents.Length);
}
public static int GetPaddedLength(int length)
{
int terminatedLength = length + 1;
int paddedLength = (int)(Math.Ceiling(terminatedLength / (float)PaddingLength) * 4);
return paddedLength;
}
public static OSCString Parse(BinaryReader reader)
{
List<byte> bytes = new List<byte>();
byte current = reader.ReadByte();
while(current != 0)
{
bytes.Add(current);
current = reader.ReadByte();
}
string str = Encoding.ASCII.GetString(bytes.ToArray());
OSCString oscString = new OSCString(str);
int bytesToBurn = oscString.Bytes.Length - bytes.Count - 1;
for(int i = 0; i < bytesToBurn; i++)
{
reader.ReadByte();
}
return oscString;
}
}
I try DataWriter and StreamWrite, dont work too well.
The UWP take out the socket class, is there any Streamwrite can do the job?
I figure this out
var socket = new DatagramSocket();
//socket.MessageReceived += SocketOnMessageReceived;
using (var stream = await socket.GetOutputStreamAsync(remoteHost, remotePort))
{
using (var writer = new DataWriter(stream))
{
// var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(packet.Bytes);
writer.StoreAsync();
}
}
Everything works great!!!!!!!!!

Asynchronous socket + waitone()

Let's start with some code:
class InternetConnector
{
private struct ConnectionData
{
public Action<Socket> SuccessHandler { get; set; }
public ClientStateObject clientObj { get; set; }
public Action<Exception> ErrorHandler { get; set; }
public Socket Socket { get; set; }
}
public static ManualResetEvent processingDone = new ManualResetEvent( false );
public static ConcurrentQueue<string> messages = new ConcurrentQueue<string>();
public bool ReceiveMessage(Action<Socket> successHandler, Action<Exception> errorHandler)
{
ClientStateObject obj = new ClientStateObject();
obj.server = client;
var connectionData = new ConnectionData
{
ErrorHandler = errorHandler,
SuccessHandler = successHandler,
Socket = client,
clientObj = obj
};
if (Connected)
{
client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
receive = true;
receiveDone.WaitOne();
}
return receive;
}
private static void ReceiveCallback(IAsyncResult ar)
{
ConnectionData connectionData = new ConnectionData();
bool complete = false;
try
{
connectionData = (ConnectionData)ar.AsyncState;
Socket client = connectionData.Socket;
int num = client.EndReceive(ar);
{
connectionData.clientObj.stringBuffer.Append(Encoding.ASCII.GetString(connectionData.clientObj.buffer, 0, num));
string response = connectionData.clientObj.stringBuffer.ToString();
string[] msgs = response.Split('&');
for (int i = 0; i < msgs.Count(); i++)
{
string sts = msgs[i];
messages.Enqueue(sts + "&" );
}
receiveDone.Set();
if (connectionData.SuccessHandler != null)
{
connectionData.SuccessHandler(client);
processingDone.WaitOne();
client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
}
}
}
catch (Exception e)
{
if (connectionData.ErrorHandler != null)
connectionData.ErrorHandler(e);
}
}
public partial class Form1 : Form
{
private InternetConnector client = new InternetConnector();
private bool isRunning = false;
private void AsyncSuccessHandler(Socket socket)
{
if (InvokeRequired)
{
BeginInvoke(new Action( () => AsyncSuccessHandler( socket ) ));
return;
}
if (InternetConnector.messages.Count() == 0)
{
status.Text = "Signals Receiver: Connected";
status.ForeColor = Color.Green;
isRunning = true;
client.ReceiveMessage(AsyncSuccessHandler, AsyncErrorHandler);
}
else
{
GUIChangeOnConnection();
InternetConnector.processingDone.Set();
}
}
private void GUIChangeOnConnection()
{
for( int i = 0; i < InternetConnector.messages.Count; i++ )
{
string message;
InternetConnector.messages.TryDequeue( out message );
// process the message
}
}
}
Now the problem.
Everything works fine. Reading from the socket is happening. However the call processingDone.WaitOne(); which should block the callback indefinitely until the call to processingDone.Set(); returns too early.
I verified it by setting the breakpoint at the end of the GUIChangeOnConnection(); - function closing bracket line. It hits the breakpoint and looking at the InternetConnector.messages I see that the queue is not empty, which means that the for loop did not finish.
And the second time this breakpoint is hit the number of messages in the queue is sky-rocketing.
What am I doing wrong? Or maybe my design is incorrect?
Thank you.

Categories

Resources