1

我试图掌握 C#/.NET 中的异步编程。我在布朗大学网站上阅读了一篇关于 cs168 课程的文章(链接),该课程将异步编程定义为同一线程中的交错任务。它说,“现在我们可以引入异步模型......在这个模型中,任务是相互交错的,但在一个控制线程中”,并在图中非常清楚地显示了交错。但我似乎无法让两个任务在 .NET 的同一个线程中交错。有没有办法做到这一点?

我写了一些简单的应用程序来尝试测试这个理论,但我不确定我是否做得正确。主程序每隔一段时间输出到屏幕上,Thread.Sleep()用来模拟工作。异步任务也是如此。如果使用多个线程,则输出是交错的。但我正在尝试在单个线程上进行测试。

我有一个在 UI 线程上运行所有内容的 WPF 应用程序,但任务和主程序始终按顺序输出。我创建并启动这样的任务:

var taskFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
var task = taskFactory.StartNew(workDelegate);

我有一个控制台应用程序,它使用 启动任务委托Task.Run(workDelegate);,但在不同的线程池线程上运行它们。我不确定如何让它们都在同一个线程上运行。如果我尝试在 WPF 中使用的相同方法,则会收到运行时 InvalidOperationException,“当前 SynchronizationContext 可能无法用作 TaskScheduler”。

4

2 回答 2

4

Multiple tasks won't automatically be interleaved on a single thread. To do that, you have to specify the points in task code where the thread is allowed to cut over to another task. You can do this via a mechanism like await Task.Yield. If you're running on a single thread, the thread will not be able to allow other work to progress unless it explicitly yields.

When you use your TaskScheduler to start every task, the message pump in WPF schedules each task to run on the UI thread, and they will run sequentially.

I have a console app that starts the task delegate using Task.Run(workDelegate);, but that runs them on different thread pool threads. I'm not sure how to make them both run on the same thread.

You would need to install a custom SynchronizationContext into a thread which allowed you to post work to that thread.

于 2013-05-14T18:09:46.340 回答
0

You cannot run two concurrent Tasks in the same thread-pool thread. Each thread-pool thread can run one Task at a time. If you want to do two things in one thread, your options what I see now: 1. Combine the two things into one Task 2. Create two tasks and one would depend on the other one. SO in the end they would run sequentially after each other. By default it's not guaranteed that they would run in the same thread though, but you should not rely on that anyway.

It's not clear to me what you want to do. According to the books the UI and the thread of your WPF should do any heavy lifting number crunching work. It should take care of the UI and organize the worker threads/tasks. You would start operations in the background using async.

于 2013-05-14T18:09:22.890 回答