首页 / C# / c# – 如何排队/等待TPL任务完成
c# – 如何排队/等待TPL任务完成
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 如何排队/等待TPL任务完成,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2738字,纯文字阅读大概需要4分钟。
内容图文
![c# – 如何排队/等待TPL任务完成](/upload/InfoBanner/zyjiaocheng/777/d3aa83566015476cac38e1f30d7e4e1d.jpg)
我需要TPL和Tasks的一些帮助
这是我的场景:
>我有一些生成任务的事件处理程序.如果在上一个任务完成之前调用了一个事件,我想在继续之前等待(阻止)它.
>我有一个同步方法,在调用之前,必须等到任何事件处理程序中的任何衍生任务完成后再继续.
public void DoSomething()
{
// Expects any running tasks from OnEvent1(), OnEvent2(), OnEvent3()
// to be completed before proceeding.
}
public void OnEvent1()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent2()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent3()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
实际情况是:
> OnFetchData()=>产卵任务.所有后续调用都需要排队.
> OnSyncSettings()=>产卵任务.所有后续调用都需要排队.
> OnAutoBackup()=>同步方法.在保存之前等待任何其他任务(例如,获取数据/同步设置)完成.
> OnFullBackup()=>同步方法.手动运行FetchData()和SyncSettings(),等待完成,继续.
我的问题很简单:我怎么能这样做?
这种方法是否正确?
>每个事件处理程序都会记住它的最后一个.调用时,它将等待其列表中的所有任务完成后再继续.
>对于同步方法,它需要等待所有任务(从每个事件处理程序)到
Task _lastEvent1Task;
public void OnEvent1()
{
// Wait for all tasks to complete before proceeding
if (_lastEvent1Task!=null)
_lastEvent1Task.Clear();
// Spawns new task
_lastEvent1Task = Task.Factory.StartNew(()=>{ });
}
public void OnEvent3()
{
// Wait for any running tasks to complete before proceeding
if (_lastEvent1Task != null) _lastEvent1Task.Wait();
if (_lastEvent2Task != null) _lastEvent2Task.Wait();
...
// Proceed
}
谢谢!
[编辑]
当DoSomething()等待并引发Event1时?
如果DoSomething()正在运行并引发事件怎么办?
OnEvents()
>如果第一个任务:生成任务并异步执行
>如果上一个任务仍在运行,则排队/阻止.关键部分.
>假设:
>这些事件通常不会多次提升.
> UI预计会阻止用户在仍在运行时引发相同的事件.
DoSomething()(调用时)
>假设:禁用事件通知.
>假设:没有新事件排队.
>预期:等待所有剩余的排队任务完成后再继续
>预期:成为同步调用,并且在执行之前不会返回调用者
解决方法:
您描述的方法存在并发问题.例如,在对_lastEvent1Task进行空检查之后,其他一些线程可能会将_lastEvent1Task设置为null,从而导致NullReferenceException.
我假设每个任务都应该同步运行,但有些不应该阻塞.实现这一目标的最佳方法是使用仅使用单个线程的TaskScheduler,您可以找到示例here.
var scheduler = new SingleThreadedTaskScheduler();
var taskFactory = new TaskFactory(scheduler);
对于非阻塞方法,您可以得到如下内容:
public void NonBlockingMethod()
{
taskFactory
.StartNew(() => { /* Long-running work. */ })
.ContinueWith(t => { /* Update UI. */ });
}
对于阻止方法,您获得:
public void BlockingMethod()
{
taskFactory
.StartNew(() => { /* Do work. */ })
.Wait();
}
在计划任务时,任务计划程序将仅使用一个线程来计划它们,从而保证所有任务同步运行.
内容总结
以上是互联网集市为您收集整理的c# – 如何排队/等待TPL任务完成全部内容,希望文章能够帮你解决c# – 如何排队/等待TPL任务完成所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。