Commit 2656df97 authored by Stéphane Graziano's avatar Stéphane Graziano Committed by Jehonathan Thomas

- IsClosed doesn't solve the memleak (streams are still blocked inside...

- IsClosed doesn't solve the memleak (streams are still blocked inside SslStream), only throwing an exception can fix that behavior.
- BeginWrite was not correct, we should call this.WriteAsync instead of baseStream.WriteAsync rewritten
parent d6638901
......@@ -471,6 +471,7 @@ namespace StreamExtended.Network
else
{
closed = true;
throw new EndOfStreamException();
}
return result;
......@@ -514,6 +515,7 @@ namespace StreamExtended.Network
else
{
closed = true;
throw new EndOfStreamException();
}
return result;
......@@ -625,7 +627,7 @@ namespace StreamExtended.Network
{
//use TaskExtended to pass State as AsyncObject
//callback will call EndRead (otherwise, it will block)
callback(new TaskResult<int>(pAsyncResult, state));
callback?.Invoke(new TaskResult<int>(pAsyncResult, state));
});
return vAsyncResult;
......@@ -640,6 +642,7 @@ namespace StreamExtended.Network
return ((TaskResult<int>)asyncResult).Result;
}
/// <summary>
/// Fix the .net bug with SslStream slow WriteAsync
/// https://github.com/justcoding121/Titanium-Web-Proxy/issues/495
......@@ -649,13 +652,20 @@ namespace StreamExtended.Network
/// <returns></returns>
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
return baseStream.BeginWrite(buffer, offset, count, callback, state);
}
var vAsyncResult = this.WriteAsync(buffer, offset, count);
vAsyncResult.ContinueWith(pAsyncResult =>
{
callback?.Invoke(new TaskResult(pAsyncResult, state));
});
return vAsyncResult;
}
public override void EndWrite(IAsyncResult asyncResult)
{
baseStream.EndWrite(asyncResult);
((TaskResult)asyncResult).GetResult();
}
#endif
}
}
......@@ -7,6 +7,28 @@ using System.Threading.Tasks;
namespace StreamExtended
{
/// <summary>
/// Mimic a Task but you can set AsyncState
/// </summary>
/// <typeparam name="T"></typeparam>
public class TaskResult : IAsyncResult
{
Task Task;
object mAsyncState;
public TaskResult(Task pTask, object state)
{
Task = pTask;
mAsyncState = state;
}
public object AsyncState => mAsyncState;
public WaitHandle AsyncWaitHandle => ((IAsyncResult)Task).AsyncWaitHandle;
public bool CompletedSynchronously => ((IAsyncResult)Task).CompletedSynchronously;
public bool IsCompleted => Task.IsCompleted;
public void GetResult() { this.Task.GetAwaiter().GetResult(); }
}
/// <summary>
/// Mimic a Task<T> but you can set AsyncState
/// </summary>
......@@ -28,4 +50,6 @@ namespace StreamExtended
public bool IsCompleted => Task.IsCompleted;
public T Result => Task.Result;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment