Use ValueTask instead of Task where possible

pull/352/head
Alexey Golub 4 years ago
parent ac64d9943a
commit ba66b52fa4

@ -46,7 +46,7 @@ namespace DiscordChatExporter.Domain.Discord
); );
} }
private async Task<HttpResponseMessage> GetResponseAsync(string url) => await _httpRequestPolicy.ExecuteAsync(async () => private async ValueTask<HttpResponseMessage> GetResponseAsync(string url) => await _httpRequestPolicy.ExecuteAsync(async () =>
{ {
using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url)); using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url));
request.Headers.Authorization = _token.GetAuthorizationHeader(); request.Headers.Authorization = _token.GetAuthorizationHeader();
@ -54,7 +54,7 @@ namespace DiscordChatExporter.Domain.Discord
return await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); return await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
}); });
private async Task<JsonElement> GetJsonResponseAsync(string url) private async ValueTask<JsonElement> GetJsonResponseAsync(string url)
{ {
using var response = await GetResponseAsync(url); using var response = await GetResponseAsync(url);
@ -72,7 +72,7 @@ namespace DiscordChatExporter.Domain.Discord
return await response.Content.ReadAsJsonAsync(); return await response.Content.ReadAsJsonAsync();
} }
private async Task<JsonElement?> TryGetJsonResponseAsync(string url) private async ValueTask<JsonElement?> TryGetJsonResponseAsync(string url)
{ {
using var response = await GetResponseAsync(url); using var response = await GetResponseAsync(url);
@ -110,7 +110,7 @@ namespace DiscordChatExporter.Domain.Discord
} }
} }
public async Task<Guild> GetGuildAsync(string guildId) public async ValueTask<Guild> GetGuildAsync(string guildId)
{ {
if (guildId == Guild.DirectMessages.Id) if (guildId == Guild.DirectMessages.Id)
return Guild.DirectMessages; return Guild.DirectMessages;
@ -167,7 +167,7 @@ namespace DiscordChatExporter.Domain.Discord
yield return Role.Parse(roleJson); yield return Role.Parse(roleJson);
} }
public async Task<Member?> TryGetGuildMemberAsync(string guildId, User user) public async ValueTask<Member?> TryGetGuildMemberAsync(string guildId, User user)
{ {
if (guildId == Guild.DirectMessages.Id) if (guildId == Guild.DirectMessages.Id)
return Member.CreateForUser(user); return Member.CreateForUser(user);
@ -176,13 +176,13 @@ namespace DiscordChatExporter.Domain.Discord
return response?.Pipe(Member.Parse); return response?.Pipe(Member.Parse);
} }
private async Task<string> GetChannelCategoryAsync(string channelParentId) private async ValueTask<string> GetChannelCategoryAsync(string channelParentId)
{ {
var response = await GetJsonResponseAsync($"channels/{channelParentId}"); var response = await GetJsonResponseAsync($"channels/{channelParentId}");
return response.GetProperty("name").GetString(); return response.GetProperty("name").GetString();
} }
public async Task<Channel> GetChannelAsync(string channelId) public async ValueTask<Channel> GetChannelAsync(string channelId)
{ {
var response = await GetJsonResponseAsync($"channels/{channelId}"); var response = await GetJsonResponseAsync($"channels/{channelId}");
@ -194,7 +194,7 @@ namespace DiscordChatExporter.Domain.Discord
return Channel.Parse(response, category); return Channel.Parse(response, category);
} }
private async Task<Message?> TryGetLastMessageAsync(string channelId, DateTimeOffset? before = null) private async ValueTask<Message?> TryGetLastMessageAsync(string channelId, DateTimeOffset? before = null)
{ {
var url = new UrlBuilder() var url = new UrlBuilder()
.SetPath($"channels/{channelId}/messages") .SetPath($"channels/{channelId}/messages")

@ -85,7 +85,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
guildId ?? Guild.DirectMessages.Id, guildId ?? Guild.DirectMessages.Id,
category ?? GetDefaultCategory(type), category ?? GetDefaultCategory(type),
name, name,
topic); topic
);
} }
} }
} }

@ -18,7 +18,7 @@ namespace DiscordChatExporter.Domain.Exporting
public ChannelExporter(AuthToken token) : this(new DiscordClient(token)) {} public ChannelExporter(AuthToken token) : this(new DiscordClient(token)) {}
public async Task ExportChannelAsync(ExportRequest request, IProgress<double>? progress = null) public async ValueTask ExportChannelAsync(ExportRequest request, IProgress<double>? progress = null)
{ {
// Build context // Build context
var contextMembers = new HashSet<Member>(IdBasedEqualityComparer.Instance); var contextMembers = new HashSet<Member>(IdBasedEqualityComparer.Instance);

@ -55,7 +55,7 @@ namespace DiscordChatExporter.Domain.Exporting
} }
// HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter // HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter
public async Task<string> ResolveMediaUrlAsync(string url) public async ValueTask<string> ResolveMediaUrlAsync(string url)
{ {
if (!Request.ShouldDownloadMedia) if (!Request.ShouldDownloadMedia)
return url; return url;

@ -22,7 +22,7 @@ namespace DiscordChatExporter.Domain.Exporting
} }
// HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter // HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter
public async Task<string> DownloadAsync(string url) public async ValueTask<string> DownloadAsync(string url)
{ {
if (_mediaPathMap.TryGetValue(url, out var cachedFilePath)) if (_mediaPathMap.TryGetValue(url, out var cachedFilePath))
return cachedFilePath; return cachedFilePath;

@ -25,7 +25,7 @@ namespace DiscordChatExporter.Domain.Exporting
_context.Request.PartitionLimit != 0 && _context.Request.PartitionLimit != 0 &&
_messageCount % _context.Request.PartitionLimit == 0; _messageCount % _context.Request.PartitionLimit == 0;
private async Task ResetWriterAsync() private async ValueTask ResetWriterAsync()
{ {
if (_writer != null) if (_writer != null)
{ {
@ -35,7 +35,7 @@ namespace DiscordChatExporter.Domain.Exporting
} }
} }
private async Task<MessageWriter> GetWriterAsync() private async ValueTask<MessageWriter> GetWriterAsync()
{ {
// Ensure partition limit has not been exceeded // Ensure partition limit has not been exceeded
if (IsPartitionLimitReached()) if (IsPartitionLimitReached())
@ -60,7 +60,7 @@ namespace DiscordChatExporter.Domain.Exporting
return _writer = writer; return _writer = writer;
} }
public async Task ExportMessageAsync(Message message) public async ValueTask ExportMessageAsync(Message message)
{ {
var writer = await GetWriterAsync(); var writer = await GetWriterAsync();
await writer.WriteMessageAsync(message); await writer.WriteMessageAsync(message);

@ -21,10 +21,10 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
private string FormatMarkdown(string? markdown) => private string FormatMarkdown(string? markdown) =>
PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); PlainTextMarkdownVisitor.Format(Context, markdown ?? "");
public override async Task WritePreambleAsync() => public override async ValueTask WritePreambleAsync() =>
await _writer.WriteLineAsync("AuthorID,Author,Date,Content,Attachments,Reactions"); await _writer.WriteLineAsync("AuthorID,Author,Date,Content,Attachments,Reactions");
private async Task WriteAttachmentsAsync(IReadOnlyList<Attachment> attachments) private async ValueTask WriteAttachmentsAsync(IReadOnlyList<Attachment> attachments)
{ {
var buffer = new StringBuilder(); var buffer = new StringBuilder();
@ -38,7 +38,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteAsync(CsvEncode(buffer.ToString())); await _writer.WriteAsync(CsvEncode(buffer.ToString()));
} }
private async Task WriteReactionsAsync(IReadOnlyList<Reaction> reactions) private async ValueTask WriteReactionsAsync(IReadOnlyList<Reaction> reactions)
{ {
var buffer = new StringBuilder(); var buffer = new StringBuilder();
@ -56,7 +56,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteAsync(CsvEncode(buffer.ToString())); await _writer.WriteAsync(CsvEncode(buffer.ToString()));
} }
public override async Task WriteMessageAsync(Message message) public override async ValueTask WriteMessageAsync(Message message)
{ {
// Author ID // Author ID
await _writer.WriteAsync(CsvEncode(message.Author.Id)); await _writer.WriteAsync(CsvEncode(message.Author.Id));

@ -102,7 +102,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
private string FormatMarkdown(string? markdown, bool isJumboAllowed = true) => private string FormatMarkdown(string? markdown, bool isJumboAllowed = true) =>
HtmlMarkdownVisitor.Format(Context, markdown ?? "", isJumboAllowed); HtmlMarkdownVisitor.Format(Context, markdown ?? "", isJumboAllowed);
private async Task WriteCurrentMessageGroupAsync() private async ValueTask WriteCurrentMessageGroupAsync()
{ {
var templateContext = CreateTemplateContext(new Dictionary<string, object> var templateContext = CreateTemplateContext(new Dictionary<string, object>
{ {
@ -112,13 +112,13 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await templateContext.EvaluateAsync(_messageGroupTemplate.Page); await templateContext.EvaluateAsync(_messageGroupTemplate.Page);
} }
public override async Task WritePreambleAsync() public override async ValueTask WritePreambleAsync()
{ {
var templateContext = CreateTemplateContext(); var templateContext = CreateTemplateContext();
await templateContext.EvaluateAsync(_preambleTemplate.Page); await templateContext.EvaluateAsync(_preambleTemplate.Page);
} }
public override async Task WriteMessageAsync(Message message) public override async ValueTask WriteMessageAsync(Message message)
{ {
// If message group is empty or the given message can be grouped, buffer the given message // If message group is empty or the given message can be grouped, buffer the given message
if (!_messageGroupBuffer.Any() || MessageGroup.CanJoin(_messageGroupBuffer.Last(), message)) if (!_messageGroupBuffer.Any() || MessageGroup.CanJoin(_messageGroupBuffer.Last(), message))
@ -138,7 +138,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
_messageCount++; _messageCount++;
} }
public override async Task WritePostambleAsync() public override async ValueTask WritePostambleAsync()
{ {
// Flush current message group // Flush current message group
if (_messageGroupBuffer.Any()) if (_messageGroupBuffer.Any())

@ -25,7 +25,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
private string FormatMarkdown(string? markdown) => private string FormatMarkdown(string? markdown) =>
PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); PlainTextMarkdownVisitor.Format(Context, markdown ?? "");
private async Task WriteAttachmentAsync(Attachment attachment) private async ValueTask WriteAttachmentAsync(Attachment attachment)
{ {
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -38,7 +38,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedAuthorAsync(EmbedAuthor embedAuthor) private async ValueTask WriteEmbedAuthorAsync(EmbedAuthor embedAuthor)
{ {
_writer.WriteStartObject("author"); _writer.WriteStartObject("author");
@ -52,7 +52,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedThumbnailAsync(EmbedImage embedThumbnail) private async ValueTask WriteEmbedThumbnailAsync(EmbedImage embedThumbnail)
{ {
_writer.WriteStartObject("thumbnail"); _writer.WriteStartObject("thumbnail");
@ -66,7 +66,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedImageAsync(EmbedImage embedImage) private async ValueTask WriteEmbedImageAsync(EmbedImage embedImage)
{ {
_writer.WriteStartObject("image"); _writer.WriteStartObject("image");
@ -80,7 +80,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedFooterAsync(EmbedFooter embedFooter) private async ValueTask WriteEmbedFooterAsync(EmbedFooter embedFooter)
{ {
_writer.WriteStartObject("footer"); _writer.WriteStartObject("footer");
@ -93,7 +93,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedFieldAsync(EmbedField embedField) private async ValueTask WriteEmbedFieldAsync(EmbedField embedField)
{ {
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -105,7 +105,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteEmbedAsync(Embed embed) private async ValueTask WriteEmbedAsync(Embed embed)
{ {
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -138,7 +138,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
private async Task WriteReactionAsync(Reaction reaction) private async ValueTask WriteReactionAsync(Reaction reaction)
{ {
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -156,7 +156,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
public override async Task WritePreambleAsync() public override async ValueTask WritePreambleAsync()
{ {
// Root object (start) // Root object (start)
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -188,7 +188,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.FlushAsync(); await _writer.FlushAsync();
} }
public override async Task WriteMessageAsync(Message message) public override async ValueTask WriteMessageAsync(Message message)
{ {
_writer.WriteStartObject(); _writer.WriteStartObject();
@ -241,7 +241,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
_messageCount++; _messageCount++;
} }
public override async Task WritePostambleAsync() public override async ValueTask WritePostambleAsync()
{ {
// Message array (end) // Message array (end)
_writer.WriteEndArray(); _writer.WriteEndArray();

@ -17,11 +17,11 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
Context = context; Context = context;
} }
public virtual Task WritePreambleAsync() => Task.CompletedTask; public virtual ValueTask WritePreambleAsync() => default;
public abstract Task WriteMessageAsync(Message message); public abstract ValueTask WriteMessageAsync(Message message);
public virtual Task WritePostambleAsync() => Task.CompletedTask; public virtual ValueTask WritePostambleAsync() => default;
public virtual async ValueTask DisposeAsync() => await Stream.DisposeAsync(); public virtual async ValueTask DisposeAsync() => await Stream.DisposeAsync();
} }

@ -24,7 +24,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
private string FormatMarkdown(string? markdown) => private string FormatMarkdown(string? markdown) =>
PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); PlainTextMarkdownVisitor.Format(Context, markdown ?? "");
private async Task WriteMessageHeaderAsync(Message message) private async ValueTask WriteMessageHeaderAsync(Message message)
{ {
// Timestamp & author // Timestamp & author
await _writer.WriteAsync($"[{message.Timestamp.ToLocalString(Context.Request.DateFormat)}]"); await _writer.WriteAsync($"[{message.Timestamp.ToLocalString(Context.Request.DateFormat)}]");
@ -37,7 +37,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteLineAsync(); await _writer.WriteLineAsync();
} }
private async Task WriteAttachmentsAsync(IReadOnlyList<Attachment> attachments) private async ValueTask WriteAttachmentsAsync(IReadOnlyList<Attachment> attachments)
{ {
if (!attachments.Any()) if (!attachments.Any())
return; return;
@ -50,7 +50,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteLineAsync(); await _writer.WriteLineAsync();
} }
private async Task WriteEmbedsAsync(IReadOnlyList<Embed> embeds) private async ValueTask WriteEmbedsAsync(IReadOnlyList<Embed> embeds)
{ {
foreach (var embed in embeds) foreach (var embed in embeds)
{ {
@ -90,7 +90,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
} }
} }
private async Task WriteReactionsAsync(IReadOnlyList<Reaction> reactions) private async ValueTask WriteReactionsAsync(IReadOnlyList<Reaction> reactions)
{ {
if (!reactions.Any()) if (!reactions.Any())
return; return;
@ -110,7 +110,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteLineAsync(); await _writer.WriteLineAsync();
} }
public override async Task WritePreambleAsync() public override async ValueTask WritePreambleAsync()
{ {
await _writer.WriteLineAsync('='.Repeat(62)); await _writer.WriteLineAsync('='.Repeat(62));
await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}"); await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}");
@ -129,7 +129,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
await _writer.WriteLineAsync(); await _writer.WriteLineAsync();
} }
public override async Task WriteMessageAsync(Message message) public override async ValueTask WriteMessageAsync(Message message)
{ {
await WriteMessageHeaderAsync(message); await WriteMessageHeaderAsync(message);
@ -147,7 +147,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
_messageCount++; _messageCount++;
} }
public override async Task WritePostambleAsync() public override async ValueTask WritePostambleAsync()
{ {
await _writer.WriteLineAsync('='.Repeat(62)); await _writer.WriteLineAsync('='.Repeat(62));
await _writer.WriteLineAsync($"Exported {_messageCount:N0} message(s)"); await _writer.WriteLineAsync($"Exported {_messageCount:N0} message(s)");

@ -8,7 +8,7 @@ namespace DiscordChatExporter.Domain.Internal.Extensions
internal static class HttpClientExtensions internal static class HttpClientExtensions
{ {
// HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter // HACK: ConfigureAwait() is crucial here to enable sync-over-async in HtmlMessageWriter
public static async Task DownloadAsync(this HttpClient httpClient, string uri, string outputFilePath) public static async ValueTask DownloadAsync(this HttpClient httpClient, string uri, string outputFilePath)
{ {
await using var input = await httpClient.GetStreamAsync(uri).ConfigureAwait(false); await using var input = await httpClient.GetStreamAsync(uri).ConfigureAwait(false);
var output = File.Create(outputFilePath); var output = File.Create(outputFilePath);
@ -17,7 +17,7 @@ namespace DiscordChatExporter.Domain.Internal.Extensions
await output.DisposeAsync().ConfigureAwait(false); await output.DisposeAsync().ConfigureAwait(false);
} }
public static async Task<JsonElement> ReadAsJsonAsync(this HttpContent content) public static async ValueTask<JsonElement> ReadAsJsonAsync(this HttpContent content)
{ {
await using var stream = await content.ReadAsStreamAsync(); await using var stream = await content.ReadAsStreamAsync();
using var doc = await JsonDocument.ParseAsync(stream); using var doc = await JsonDocument.ParseAsync(stream);

@ -22,7 +22,7 @@ namespace DiscordChatExporter.Domain.Utilities
public static ValueTaskAwaiter<IReadOnlyList<T>> GetAwaiter<T>(this IAsyncEnumerable<T> asyncEnumerable) => public static ValueTaskAwaiter<IReadOnlyList<T>> GetAwaiter<T>(this IAsyncEnumerable<T> asyncEnumerable) =>
asyncEnumerable.AggregateAsync().GetAwaiter(); asyncEnumerable.AggregateAsync().GetAwaiter();
public static async Task ParallelForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> handleAsync, int degreeOfParallelism) public static async ValueTask ParallelForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> handleAsync, int degreeOfParallelism)
{ {
using var semaphore = new SemaphoreSlim(degreeOfParallelism); using var semaphore = new SemaphoreSlim(degreeOfParallelism);

@ -23,7 +23,7 @@ namespace DiscordChatExporter.Gui.Services
_settingsService = settingsService; _settingsService = settingsService;
} }
public async Task<Version?> CheckForUpdatesAsync() public async ValueTask<Version?> CheckForUpdatesAsync()
{ {
if (!_settingsService.IsAutoUpdateEnabled) if (!_settingsService.IsAutoUpdateEnabled)
return null; return null;
@ -32,7 +32,7 @@ namespace DiscordChatExporter.Gui.Services
return check.CanUpdate ? check.LastVersion : null; return check.CanUpdate ? check.LastVersion : null;
} }
public async Task PrepareUpdateAsync(Version version) public async ValueTask PrepareUpdateAsync(Version version)
{ {
if (!_settingsService.IsAutoUpdateEnabled) if (!_settingsService.IsAutoUpdateEnabled)
return; return;

@ -17,7 +17,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
_viewManager = viewManager; _viewManager = viewManager;
} }
public async Task<T> ShowDialogAsync<T>(DialogScreen<T> dialogScreen) public async ValueTask<T> ShowDialogAsync<T>(DialogScreen<T> dialogScreen)
{ {
// Get the view that renders this viewmodel // Get the view that renders this viewmodel
var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen); var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen);

@ -70,7 +70,7 @@ namespace DiscordChatExporter.Gui.ViewModels
(sender, args) => IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress.IsEither(0, 1)); (sender, args) => IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress.IsEither(0, 1));
} }
private async Task HandleAutoUpdateAsync() private async ValueTask HandleAutoUpdateAsync()
{ {
try try
{ {

Loading…
Cancel
Save