Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ListenOnce extension breaks AOT #157

Merged
merged 3 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Core Modules/WalletConnectSharp.Common/Utils/EventUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace WalletConnectSharp.Common.Utils;

public class EventUtils
{
/// <summary>
/// Invoke the given event handler once and then unsubscribe it.
/// Use with abstract events. Otherwise, use the extension method as it is more efficient.
/// </summary>
/// <example>
/// <code>
/// EventUtils.ListenOnce((_, _) => WCLogger.Log("Resubscribed")),
/// h => this.Subscriber.Resubscribed += h,
/// h => this.Subscriber.Resubscribed -= h
/// );
/// </code>
/// </example>
public static Action ListenOnce(
EventHandler handler,
Action<EventHandler> subscribe,
Action<EventHandler> unsubscribe)
{
EventHandler internalHandler = null;
internalHandler = (sender, args) =>
{
unsubscribe(internalHandler);
handler(sender, args);
};

subscribe(internalHandler);

return () => unsubscribe(internalHandler);
}

/// <summary>
/// Invoke the given event handler once and then unsubscribe it.
/// Use with abstract events. Otherwise, use the extension method as it is more efficient.
/// </summary>
public static Action ListenOnce<TEventArgs>(
EventHandler<TEventArgs> handler,
Action<EventHandler<TEventArgs>> subscribe,
Action<EventHandler<TEventArgs>> unsubscribe)
{
EventHandler<TEventArgs> internalHandler = null;
internalHandler = (sender, args) =>
{
unsubscribe(internalHandler);
handler(sender, args);
};

subscribe(internalHandler);

return () => unsubscribe(internalHandler);
}
}
88 changes: 58 additions & 30 deletions Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/// <param name="o">The object to check</param>
/// <returns>Returns true if the object has a numeric type</returns>
public static bool IsNumericType(this object o)
{
{
switch (Type.GetTypeCode(o.GetType()))
{
case TypeCode.Byte:
Expand All @@ -29,7 +29,7 @@
return false;
}
}

/// <summary>
/// Add a query parameter to the given source string
/// </summary>
Expand Down Expand Up @@ -58,77 +58,105 @@
+ "=" + HttpUtility.UrlEncode(value);
}

public static async Task<T> WithTimeout<T>(this Task<T> task, int timeout = 1000, string message = "Timeout of %t exceeded")
public static async Task<T> WithTimeout<T>(this Task<T> task, int timeout = 1000,
string message = "Timeout of %t exceeded")
{
var resultT = await Task.WhenAny(task, Task.Delay(timeout));
if (resultT != task)
{
throw new TimeoutException(message.Replace("%t", timeout.ToString()));
}

return ((Task<T>) resultT).Result;
return ((Task<T>)resultT).Result;
}

public static async Task WithTimeout(this Task task, int timeout = 1000, string message = "Timeout of %t exceeded")

public static async Task WithTimeout(this Task task, int timeout = 1000,
string message = "Timeout of %t exceeded")
{
var resultT = await Task.WhenAny(task, Task.Delay(timeout));
if (resultT != task)
{
throw new TimeoutException(message.Replace("%t", timeout.ToString()));
}
}

public static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout, string message = "Timeout of %t exceeded")

public static async Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout,
string message = "Timeout of %t exceeded")
{
var resultT = await Task.WhenAny(task, Task.Delay(timeout));
if (resultT != task)
{
throw new TimeoutException(message.Replace("%t", timeout.ToString()));
}

return ((Task<T>) resultT).Result;
return ((Task<T>)resultT).Result;
}

public static async Task WithTimeout(this Task task, TimeSpan timeout, string message = "Timeout of %t exceeded")

public static async Task WithTimeout(this Task task, TimeSpan timeout,
string message = "Timeout of %t exceeded")
{
var resultT = await Task.WhenAny(task, Task.Delay(timeout));
if (resultT != task)
{
throw new TimeoutException(message.Replace("%t", timeout.ToString()));
}
}

public static bool SetEquals<T>(this IEnumerable<T> first, IEnumerable<T> second,
IEqualityComparer<T> comparer)
{
return new HashSet<T>(second, comparer ?? EqualityComparer<T>.Default)
.SetEquals(first);
}
public static Action ListenOnce(this object eventSource, string eventName, EventHandler handler) {
var eventInfo = eventSource.GetType().GetEvent(eventName);

public static Action ListenOnce(this EventHandler eventHandler, EventHandler handler)
{
EventHandler internalHandler = null;
internalHandler = (src, args) => {
eventInfo.RemoveEventHandler(eventSource, internalHandler);
handler(src, args);
};
void RemoveListener()
internalHandler = (sender, args) =>
{
eventInfo.RemoveEventHandler(eventSource, internalHandler);
}
eventInfo.AddEventHandler(eventSource, internalHandler);
eventHandler -= internalHandler;
handler(sender, args);
};

eventHandler += internalHandler;

return RemoveListener;
return () =>
{
try
{
eventHandler -= internalHandler;
}
catch (Exception e)

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used

Check warning on line 129 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used
{
// ignored
}
};
}

public static void ListenOnce<TEventArgs>(this object eventSource, string eventName, EventHandler<TEventArgs> handler) {
var eventInfo = eventSource.GetType().GetEvent(eventName);
public static Action ListenOnce<TEventArgs>(
this EventHandler<TEventArgs> eventHandler,
EventHandler<TEventArgs> handler)
{
EventHandler<TEventArgs> internalHandler = null;
internalHandler = (src, args) => {
eventInfo.RemoveEventHandler(eventSource, internalHandler);
handler(src, args);
internalHandler = (sender, args) =>
{
eventHandler -= internalHandler;
handler(sender, args);
};

eventHandler += internalHandler;

return () =>
{
try
{
eventHandler -= internalHandler;
}
catch (Exception e)

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (unit-tests)

The variable 'e' is declared but never used

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used

Check warning on line 155 in Core Modules/WalletConnectSharp.Common/Utils/Extensions.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

The variable 'e' is declared but never used
{
// ignored
}
};
eventInfo.AddEventHandler(eventSource, internalHandler);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@
TaskCompletionSource<WebsocketClient> registeringTask =
new TaskCompletionSource<WebsocketClient>(TaskCreationOptions.None);

this.ListenOnce<Exception>(nameof(RegisterErrored), (sender, args) =>
RegisterErrored.ListenOnce((sender, args) =>
{
registeringTask.SetException(args);
});

this.ListenOnce<WebsocketClient>(nameof(Opened), (sender, args) =>
Opened.ListenOnce((sender, args) =>
{
registeringTask.SetResult(args);
registeringTask.SetResult((WebsocketClient)args);
});

await registeringTask.Task;
Expand Down Expand Up @@ -305,7 +305,7 @@
}
}

public async void Dispose()

Check warning on line 308 in Core Modules/WalletConnectSharp.Network.Websocket/WebsocketConnection.cs

View workflow job for this annotation

GitHub Actions / build (integration-tests)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
Dispose(true);
GC.SuppressFinalize(this);
Expand Down
Loading
Loading