C# 在下面的场景中,如何将自定义对象映射到相应的任务?
我正在开发一个控制台应用程序,其中有一个第三方rest客户端wordpress rest client,确切地说,它有一些带有返回任务对象的方法。示例方法签名可以类似于:C# 在下面的场景中,如何将自定义对象映射到相应的任务?,c#,async-await,task,task-parallel-library,C#,Async Await,Task,Task Parallel Library,我正在开发一个控制台应用程序,其中有一个第三方rest客户端wordpress rest client,确切地说,它有一些带有返回任务对象的方法。示例方法签名可以类似于: public Task<bool> Delete(int id); 在这种情况下,删除是fire and forget。如果我把被删除的帖子的信息记录下来会更好。日志语句,如: logger.Log($"A post with {post.Id} is deleted"); 因此,我决定对这些任务进行规划 pu
public Task<bool> Delete(int id);
在这种情况下,删除是fire and forget。如果我把被删除的帖子的信息记录下来会更好。日志语句,如:
logger.Log($"A post with {post.Id} is deleted");
因此,我决定对这些任务进行规划
public async Task DeleteGivenPosts(List<Post> posts) {
var postDeletionTasks = posts.Select(post => wpRestClient.Delete(post.Id));
foreach (var deletionTask in TaskExtensionUtil.GetTasksInCompletingOrder(postsDeletionTasks)) {
bool deletionResult = await deletionTask;
if(deletionResult) {
//i want to log success of deletion here
} else {
//i want to log the failure of deletion here
}
}
}
问题是deletionResult是一个bool。为了记录关于删除哪个帖子的信息,我需要获取与删除任务关联的帖子对象
我想创建一个字典,通过如下操作将删除任务映射到相应的帖子:
posts.Select(post => new { deletionTask = wpRestClient.Delete(post.Id), post})
.ToDictionary(i => i.deletionTask, i => i.post);
private async Task<DeletionResult> DeletePost(int postId)
{
bool result = await wpRestClient.Delete(postId);
return new DeletionResult(result, postId);
}
但这将不起作用,因为在GetTaskCompletingOrder中,原始删除任务被转换为TaskCompletionSource任务。因此,我总是会得到一个例外,即字典中没有该键。此外,我也不确定当字典将任务对象作为键时,它将如何工作
在这一点上,我不知道如何实现日志记录。我将非常感谢您的帮助。删除后如何编写日志语句
public async Task DeleteGivenPosts(List<Post> posts)
{
await Task.WhenAll(
posts.Select(async post =>
{
bool res = await wpRestClient.Delete(post.Id);
string message = res ? $"Post {post.Id} is deleted" : $"Post {post.Id} survived!";
logger.Log(message);
}));
}
下面是一个小型LinqPad程序,用于举例说明该方法的工作原理:
async void Main()
{
List<Post> postList = Enumerable.Range(1, 12).Select(id => new Post {Id = id}).ToList();
Console.WriteLine("Start Deletion");
await DeleteGivenPosts(postList);
Console.WriteLine("Finished Deletion");
}
public static MyRestClient wpRestClient = new MyRestClient();
// Define other methods and classes here
public async Task DeleteGivenPosts(List<Post> posts)
{
await Task.WhenAll(
posts.Select(async post =>
{
bool res = await wpRestClient.Delete(post.Id);
string message = res ? $"Post {post.Id} is deleted" : $"Post {post.Id} survived!";
Console.WriteLine(message);
}));
}
public static Random rand = new Random(DateTime.Now.Millisecond);
public class MyRestClient
{
public async Task<bool> Delete(int i)
{
return await Task<bool>.Run(() => { Thread.Sleep(400); return rand.Next(1,4) == 1;});
}
}
public class Post
{
public int Id { get; set; }
}
输出:
开始删除
1号帖子被删除
3号柱幸存了!
5号柱幸存了!
6号柱幸存了!
2号哨所幸免于难!
4号柱幸存了!
8号柱幸存了!
邮政7幸存!
9号柱幸存了!
11号岗位幸存了!
第10条被删除
第12条被删除
完成删除
删除后写logstatement怎么样
public async Task DeleteGivenPosts(List<Post> posts)
{
await Task.WhenAll(
posts.Select(async post =>
{
bool res = await wpRestClient.Delete(post.Id);
string message = res ? $"Post {post.Id} is deleted" : $"Post {post.Id} survived!";
logger.Log(message);
}));
}
下面是一个小型LinqPad程序,用于举例说明该方法的工作原理:
async void Main()
{
List<Post> postList = Enumerable.Range(1, 12).Select(id => new Post {Id = id}).ToList();
Console.WriteLine("Start Deletion");
await DeleteGivenPosts(postList);
Console.WriteLine("Finished Deletion");
}
public static MyRestClient wpRestClient = new MyRestClient();
// Define other methods and classes here
public async Task DeleteGivenPosts(List<Post> posts)
{
await Task.WhenAll(
posts.Select(async post =>
{
bool res = await wpRestClient.Delete(post.Id);
string message = res ? $"Post {post.Id} is deleted" : $"Post {post.Id} survived!";
Console.WriteLine(message);
}));
}
public static Random rand = new Random(DateTime.Now.Millisecond);
public class MyRestClient
{
public async Task<bool> Delete(int i)
{
return await Task<bool>.Run(() => { Thread.Sleep(400); return rand.Next(1,4) == 1;});
}
}
public class Post
{
public int Id { get; set; }
}
输出:
开始删除
1号帖子被删除
3号柱幸存了!
5号柱幸存了!
6号柱幸存了!
2号哨所幸免于难!
4号柱幸存了!
8号柱幸存了!
邮政7幸存!
9号柱幸存了!
11号岗位幸存了!
第10条被删除
第12条被删除
完成删除
你也可以用你自己的方法来包装它,比如:
IEnumerable<Task<DeletionResult>> postDeletionTasks = posts.Select(post => DeletePost(post.Id));
这样,您将有一个任务列表,其结果包含受影响的PostId。您也可以使用自己的方法将其包装起来,如下所示:
IEnumerable<Task<DeletionResult>> postDeletionTasks = posts.Select(post => DeletePost(post.Id));
这样,您将有一个任务列表,其结果包含受影响的PostId。@NavjotSingh这意味着您需要一个等待的方法DeleteGivenPosts?还是希望用户阻止关闭您的应用程序?我必须确保在所有删除任务完成之前,应用程序不会退出。顺便问一下,在你的linqPad程序中,主方法是否会等待所有帖子被删除?不,不会,因为你的DeleteGivenPosts方法无效是的,那么我想我需要一个等待的方法。@NavjotSingh好的,那么我很高兴我们解决了你的问题。祝您有个美好的一天mate@NavjotSingh这意味着你需要一个等待的方法来删除GivenPosts?还是希望用户阻止关闭您的应用程序?我必须确保在所有删除任务完成之前,应用程序不会退出。顺便问一下,在你的linqPad程序中,主方法是否会等待所有帖子被删除?不,不会,因为你的DeleteGivenPosts方法无效是的,那么我想我需要一个等待的方法。@NavjotSingh好的,那么我很高兴我们解决了你的问题。祝你有愉快的一天,你是什么意思?我正在等待删除,但没有等待.posts.Select中的DeletePost,不确定我是否理解你的意思。我错误地理解了你的答案。我的错。我认为你的回答也解决了问题。你是什么意思?我正在等待删除,但没有等待.posts.Select中的DeletePost,不确定我是否理解你的意思。我错误地理解了你的答案。我的错。我认为你的答案也解决了问题。你真的想像火一样运行删除并忘记任务吗?@TheodorZoulias我只想执行删除。如果有失败,我只想告诉你,某个删除无法完成。我不清楚你是否故意解雇并忘记删除,因为你不在乎他们在那一刻是成功还是失败,或者你是无意中这样做的,因为你不知道如何等待他们完成后再继续。是的,我刚刚注意到,接受的答案包含使用Task.WhenAll的DeleteGivenPosts的正确版本。它还包含使用List.ForEach方法的有问题的DeleteGivenPosts。这是相当令人困惑的,因为有问题的版本位于顶部,而正确的版本是作为如何使用有问题版本的假定示例呈现的。不管怎样,你的问题现在解决了,所以一切都很好-@TheodorZoulias感谢您的评论。我从顶部删除了DeleteGivenPosts的令人困惑的问题版本,并将其与下面程序中的异步版本进行了交换。您真的想将删除作为fire and forget tasks运行吗?@TheodorZoulias我只想执行删除。如果有fai
lure我只想告诉你,某个删除无法完成。我不清楚你是否故意解雇并忘记删除,因为你不在乎他们在那一刻是成功还是失败,或者你是无意中这样做的,因为你不知道如何等待他们完成后再继续。是的,我刚刚注意到,接受的答案包含使用Task.WhenAll的DeleteGivenPosts的正确版本。它还包含使用List.ForEach方法的有问题的DeleteGivenPosts。这是相当令人困惑的,因为有问题的版本位于顶部,而正确的版本是作为如何使用有问题版本的假定示例呈现的。不管怎样,你的问题现在解决了,所以一切都很好-@TheodorZoulias感谢您的评论。我从顶部删除了DeleteGivenPosts这个令人困惑的有问题的版本,并将其与下面程序中的异步版本进行了交换。