-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from NerosoftDev/develop
Develop
- Loading branch information
Showing
207 changed files
with
6,433 additions
and
2,229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,123 @@ | ||
using System.Globalization; | ||
namespace Nerosoft.Starfish.Common; | ||
|
||
namespace Nerosoft.Starfish.Common; | ||
/// <summary> | ||
/// Provides some helper methods to work with async methods. | ||
/// </summary> | ||
public static class AsyncHelper | ||
{ | ||
private static readonly TaskFactory _factory = new(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default); | ||
|
||
public static TResult RunSync<TResult>(Func<Task<TResult>> func) | ||
{ | ||
var cultureUi = CultureInfo.CurrentUICulture; | ||
var culture = CultureInfo.CurrentCulture; | ||
return _factory.StartNew(() => | ||
var oldContext = SynchronizationContext.Current; | ||
var context = new ExclusiveSynchronizationContext(); | ||
SynchronizationContext.SetSynchronizationContext(context); | ||
TResult result = default; | ||
context.Post(async _ => | ||
{ | ||
Thread.CurrentThread.CurrentCulture = culture; | ||
Thread.CurrentThread.CurrentUICulture = cultureUi; | ||
return func(); | ||
}).Unwrap().GetAwaiter().GetResult(); | ||
try | ||
{ | ||
result = await func(); | ||
} | ||
catch (Exception exception) | ||
{ | ||
context.Exception = exception; | ||
throw; | ||
} | ||
finally | ||
{ | ||
context.EndMessageLoop(); | ||
} | ||
}, null); | ||
context.BeginMessageLoop(); | ||
SynchronizationContext.SetSynchronizationContext(oldContext); | ||
return result; | ||
} | ||
|
||
public static void RunSync(Func<Task> func) | ||
{ | ||
var cultureUi = CultureInfo.CurrentUICulture; | ||
var culture = CultureInfo.CurrentCulture; | ||
_factory.StartNew(() => | ||
var oldContext = SynchronizationContext.Current; | ||
var context = new ExclusiveSynchronizationContext(); | ||
SynchronizationContext.SetSynchronizationContext(context); | ||
context.Post(async _ => | ||
{ | ||
try | ||
{ | ||
await func(); | ||
} | ||
catch (Exception exception) | ||
{ | ||
context.Exception = exception; | ||
throw; | ||
} | ||
finally | ||
{ | ||
context.EndMessageLoop(); | ||
} | ||
}, null); | ||
context.BeginMessageLoop(); | ||
|
||
SynchronizationContext.SetSynchronizationContext(oldContext); | ||
} | ||
|
||
private class ExclusiveSynchronizationContext : SynchronizationContext | ||
{ | ||
private bool done; | ||
public Exception Exception { get; set; } | ||
readonly AutoResetEvent workItemsWaiting = new(false); | ||
readonly Queue<Tuple<SendOrPostCallback, object>> items = new(); | ||
|
||
public override void Send(SendOrPostCallback d, object state) | ||
{ | ||
throw new NotSupportedException("We cannot send to our same thread"); | ||
} | ||
|
||
public override void Post(SendOrPostCallback callback, object state) | ||
{ | ||
lock (items) | ||
{ | ||
items.Enqueue(Tuple.Create(callback, state)); | ||
} | ||
workItemsWaiting.Set(); | ||
} | ||
|
||
public void EndMessageLoop() | ||
{ | ||
Post(_ => done = true, null); | ||
} | ||
|
||
public void BeginMessageLoop() | ||
{ | ||
if (done) | ||
{ | ||
return; | ||
} | ||
while (!done) | ||
{ | ||
Tuple<SendOrPostCallback, object> task = null; | ||
lock (items) | ||
{ | ||
if (items.Count > 0) | ||
{ | ||
task = items.Dequeue(); | ||
} | ||
} | ||
if (task != null) | ||
{ | ||
task.Item1(task.Item2); | ||
if (Exception != null) // the method threw an exception | ||
{ | ||
throw new AggregateException("AsyncHelper.Run method threw an exception.", Exception); | ||
} | ||
} | ||
else | ||
{ | ||
workItemsWaiting.WaitOne(); | ||
} | ||
} | ||
} | ||
|
||
public override SynchronizationContext CreateCopy() | ||
{ | ||
Thread.CurrentThread.CurrentCulture = culture; | ||
Thread.CurrentThread.CurrentUICulture = cultureUi; | ||
return func(); | ||
}).Unwrap().GetAwaiter().GetResult(); | ||
return this; | ||
} | ||
} | ||
} |
Oops, something went wrong.