Skip to content

Instantly share code, notes, and snippets.

@nathan130200
Last active May 27, 2019 18:45
Show Gist options
  • Save nathan130200/dc60db689609df90d469762762cb6983 to your computer and use it in GitHub Desktop.
Save nathan130200/dc60db689609df90d469762762cb6983 to your computer and use it in GitHub Desktop.
Small "conversion" about Android AsyncTask to .NET (+3.5) | Tested with .NET 3.5 WinForms and modify UI by other threads.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace System.Threading
{
public abstract class AsyncTaskBase
{
public SynchronizationContext Context { get; }
public AsyncTaskBase()
{
this.Context = SynchronizationContext.Current;
}
protected void Wait(int duration)
{
Thread.Sleep(duration);
}
}
public class AsyncTask : AsyncTaskBase
{
public AsyncTask() : base()
{
}
protected virtual void PreExecute()
{
throw new NotImplementedException();
}
protected virtual void DoInBackground()
{
throw new NotImplementedException();
}
protected virtual void PostExecute(AsyncTaskResult result)
{
throw new NotImplementedException();
}
protected void Wait(TimeSpan duration)
{
Thread.Sleep(duration);
}
public void Start()
{
new Thread(() =>
{
this.Context.Post(_ => this.PreExecute(), null);
Exception error = null;
try
{
this.DoInBackground();
}
catch (Exception ex)
{
error = ex;
}
this.Context.Post(_ => this.PostExecute(new AsyncTaskResult(error)), null);
}).Start();
}
}
public class AsyncTask<TInput> : AsyncTaskBase
{
protected virtual void PreExecute()
{
throw new NotImplementedException();
}
protected virtual void DoInBackground(TInput input)
{
throw new NotImplementedException();
}
protected virtual void PostExecute(AsyncTaskResult result)
{
throw new NotImplementedException();
}
public void Start(TInput input)
{
new Thread(() =>
{
this.Context.Post(_ => this.PreExecute(), null);
Exception error = null;
try
{
this.DoInBackground(input);
}
catch (Exception ex)
{
error = ex;
}
this.Context.Post(_ => this.PostExecute(new AsyncTaskResult(error)), null);
}).Start();
}
}
public class AsyncTask<TInput, TOutput> : AsyncTaskBase
{
protected virtual void PreExecute()
{
throw new NotImplementedException();
}
protected virtual TOutput DoInBackground(TInput input)
{
throw new NotImplementedException();
}
protected virtual void PostExecute(AsyncTaskResult<TOutput> result)
{
throw new NotImplementedException();
}
public void Start(TInput input)
{
new Thread(() =>
{
this.Context.Post(_ => this.PreExecute(), null);
TOutput result = default;
Exception error = null;
try
{
result = this.DoInBackground(input);
}
catch (Exception ex)
{
error = ex;
}
this.Context.Post(_ => this.PostExecute(new AsyncTaskResult<TOutput>(result, error)), null);
}).Start();
}
}
public class AsyncTaskResult
{
public AsyncTaskResult(Exception error)
{
this.Error = error;
}
public Exception Error { get; }
}
public class AsyncTaskResult<T> : AsyncTaskResult
{
public AsyncTaskResult(T result, Exception error) : base(error)
{
this.Result = result;
}
public T Result { get; }
}
}
public class ShutdownTask : AsyncTask
{
// As we know, we can not change the UI of a thread in which we did not instantiate the original control.
// With this small "AsyncTask" wrapper we can do into PreExecute and PostExecute methods!
// tested and working here!
ServerControl sc;
public ShutdownTask(ServerControl sc)
{
this.sc = sc;
}
protected override void PreExecute()
{
sc.m_closed_started = true;
}
protected override void DoInBackground()
{
sc.Call(ctx => ctx.Enabled = false);
if (sc.m_process != null)
{
sc.m_process.StandardInput.WriteLine("stop"); // comando mais usado para finalizar um servidor de minecraft.
sc.m_process.StandardInput.Flush();
Wait(TimeSpan.FromSeconds(10));
sc.m_process.Refresh();
if (!sc.m_process.HasExited)
sc.m_process.Kill();
}
}
protected override void PostExecute(AsyncTaskResult result)
{
sc.m_closed = true;
sc.OnShutdown?.Invoke();
//sc.Call(ctx => );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment