Skip to content

Instantly share code, notes, and snippets.

@Benedicht
Last active August 29, 2015 14:18
Show Gist options
  • Select an option

  • Save Benedicht/cc0dfdaeaa0f5e1e16a6 to your computer and use it in GitHub Desktop.

Select an option

Save Benedicht/cc0dfdaeaa0f5e1e16a6 to your computer and use it in GitHub Desktop.
Helper class to be able send a blocking HTTPRequest - BestHTTP(http://u3d.as/5sb)
/// <summary>
/// Helper class to be able send a blocking HTTPRequest
/// </summary>
public sealed class BlockingRequestHelper
{
#region Private Fields
/// <summary>
/// AutResetEvent to wait for the request
/// </summary>
AutoResetEvent mre = new AutoResetEvent(false);
/// <summary>
/// AutResetEvent to pause the thread
/// </summary>
AutoResetEvent threadPing = new AutoResetEvent(false);
/// <summary>
/// Thread to call HTTPManager.OnUpdate
/// </summary>
Thread thread;
/// <summary>
/// While true, HTTPManager.OnUpdate will be called
/// </summary>
bool doUpdate;
/// <summary>
/// While true, the thread will not quit
/// </summary>
bool threadAlive;
/// <summary>
/// To save the originally set callback
/// </summary>
OnRequestFinishedDelegate originalCallback;
#endregion
#region Public Functions
/// <summary>
/// This will send the request and will block until it's finished
/// </summary>
public void SendAndWait(HTTPRequest request)
{
HTTPManager.Logger.Information("BlockingRequest", "Sending Request...");
// This must be called on Unity's main thread
HTTPManager.Setup();
// Save the callback
originalCallback = request.Callback;
// Set a new callback, where we will ping the ManualResetEvent
request.Callback = (req, resp) => mre.Set();
// Send the request
request.Send();
// Start or resume our thread to do OnUpdates
StartThread();
// Block until the request's hijacked callback is called and will set the ManualResetEvent
mre.WaitOne();
// Pause the thread
PauseThread();
// Call the originally set callback on the main thread
if (originalCallback != null)
{
try
{
originalCallback(request, request.Response);
}
catch(Exception ex)
{
HTTPManager.Logger.Exception("BlockingRequest", "calling originalCallback", ex);
}
}
HTTPManager.Logger.Information("BlockingRequest", "Request Done!");
}
/// <summary>
/// This will stop the started thread. Call it when no more SendAndWait will be called
/// </summary>
public void StopThread()
{
if (thread != null)
{
HTTPManager.Logger.Information("BlockingRequest", "Stopping Thread");
thread = null;
doUpdate = false;
threadAlive = false;
threadPing.Set();
}
}
#endregion
#region Private Helper Functions
void StartThread()
{
// Start a thread
if (thread == null)
{
HTTPManager.Logger.Information("BlockingRequest", "Starting new Thread");
thread = new Thread(new ThreadStart(ThreadFunc));
doUpdate = true;
threadAlive = true;
thread.Start();
}
else
{
// Resume updating
HTTPManager.Logger.Information("BlockingRequest", "Resuming Thread");
doUpdate = true;
threadPing.Set();
}
}
void PauseThread()
{
doUpdate = false;
}
void ThreadFunc()
{
HTTPManager.Logger.Information("BlockingRequest", "Thread Started");
while (threadAlive)
{
while (doUpdate)
{
// Don't eat all cpu cycles
Thread.Sleep(100);
HTTPManager.OnUpdate();
}
HTTPManager.Logger.Information("BlockingRequest", "Thread Paused");
threadPing.WaitOne();
HTTPManager.Logger.Information("BlockingRequest", "Thread Resumed");
}
HTTPManager.Logger.Information("BlockingRequest", "Thread Quit");
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment