动态链接"Task< T>"而不会阻塞线程

编程入门 行业动态 更新时间:2024-10-28 08:22:05
本文介绍了动态链接"Task< T>"而不会阻塞线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试像在JavaScript中那样在C#中链接 Task< T> 对象,并且不阻塞UI线程.

I am trying to chain Task<T> objects in C# as done in JavaScript and without blocking the UI thread.

我在此处看到了类似的问题,但是它使用非泛型 Task 对象作为流程函数的返回类型.我尝试对 Task< T> 做同样的事情.

I see there is a similar question here, but it uses the non-generic Task object as a return type of the process functions. I try to do the same with Task<T>.

我还看到此处是我的一个更接近的问题需要,但可接受的答案似乎两次使用 .Result ,我想这会阻塞UI线程.另外,请注意,我是动态链接任务的,因此我无法遵循一些简单的解决方法.此外, Then 实现还提供了这里似乎也是同步的(我不确定是否只需更改此旧示例代码上的 TaskContinuationOptions 即可实现我想要的功能).

I also see that here is a closer question to my needs, but the accepted answer seems to use .Result twice, which I guess will block the UI thread. Also, note that I chain tasks dynamically, so I can't follow some easy workarounds. And also, the Then implementation given here seems synchronous too (I am not sure if simply changing the TaskContinuationOptions on this old sample code will do what I want).

这是我现在拥有的,但是如果不阻塞线程,我什至无法编译它:

Here is what I have right now, but I can't even make it compile without blocking the thread:

// Initial dummy task. private Task<bool> taskChain = Task.Factory.StartNew<bool>(() => true); // Chain dynamically on button click. private async void DoSth_Click(object sender, RoutedEventArgs e) { var data = ....; System.Threading.Tasks.Task<bool> del = async (t) => { return await ConvertAsync(data); }; taskChain = taskChain.ContinueWith<bool>(() => del); var res = await taskChain; }

我尝试了各种不同的方法,但是我不知道如何将 Task< T> 转换为 Func< Task< T>,T> code> ContinueWith< bool>()似乎是必需的(至少没有做一些讨厌的UI线程阻塞操作).

I have tried various different approaches, but I don't see how I can turn Task<T> to Func<Task<T>, T> that ContinueWith<bool>() seems to require (at least without doing some nasty UI thread blocking operation).

我希望这很容易,但是我在这里看不到解决方案……难道没有一个简便的方法吗?

I would expect this to be easy, but I don't quite see the solution here... Isn't there a good and easy way to do this?

(注意:我想我应该在 ContinueWith()之后调用 Unwrap(),但是这时似乎很详细...)

(Note: I guess I should probably call Unwrap() after the ContinueWith() but this seems like a detail at this point...)

推荐答案

UnWrap 是您的朋友.它将使您拥有一个可以解析为 Task 的延续方法,然后在延续被触发之前获得一个代表该任务的 Task .

UnWrap is your friend here. It'll allow you to have a continuation method that resolves to a Task, and then get a Task that represents that task before the continuation has even fired.

还请注意,应使用 FromResult 创建已完成的任务.

Also note that FromResult should be used to create an already completed task.

private Task<bool> taskChain = Task.FromResult(true); private async void DoSth_Click(object sender, RoutedEventArgs e) { var data = CreateData(); taskChain = taskChain.ContinueWith(t => ConvertAsync(data)) .Unwrap(); var res = await taskChain; }

请注意,建议您不要在点击处理程序中直接进行此操作.创建一个能够排队任务的类,然后使用 that .当然,这样的队列类也遵循相同的模式:

Note that I'd advise against doing this in-line in a click handler. Create a class that is able to queue tasks, and then use that. Of course, such a queue class is just following this same pattern:

public class TaskQueue { private Task previous = Task.FromResult(false); private object key = new object(); public Task<T> Enqueue<T>(Func<Task<T>> taskGenerator) { lock (key) { var next = previous.ContinueWith(t => taskGenerator()).Unwrap(); previous = next; return next; } } public Task Enqueue(Func<Task> taskGenerator) { lock (key) { var next = previous.ContinueWith(t => taskGenerator()).Unwrap(); previous = next; return next; } } }

这将允许您编写:

private TaskQueue taskQueue = new TaskQueue(); private async void DoSth_Click(object sender, RoutedEventArgs e) { var data = CreateData(); var res = await TaskQueue.Enqueue(ConvertAsync(data)); }

现在,您的排队任务机制已与该点击处理程序需要执行的业务逻辑分开.

Now your mechanism of queuing tasks is separated from the business logic of what this click handler needs to do.

更多推荐

动态链接"Task&lt; T&gt;"而不会阻塞线程

本文发布于:2023-06-07 22:46:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/572863.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   链接   动态   gt   Task

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!