C# 使用任务对象和监视线程的长时间运行的进程

C# 使用任务对象和监视线程的长时间运行的进程,c#,.net,c#-4.0,task-parallel-library,C#,.net,C# 4.0,Task Parallel Library,我正在尝试监视一个长时间运行的进程。现在,流程为所有小部件创建了新的任务对象,但我需要某种方法来监视它们的进度,以便将状态发送到UI ExecutionContext ctx = new ExecutionContext() { Result = result, LastCount = result.Values.Count }; Task t = Task.Factory.StartNew(()

我正在尝试监视一个长时间运行的进程。现在,流程为所有小部件创建了新的任务对象,但我需要某种方法来监视它们的进度,以便将状态发送到UI

ExecutionContext ctx = new ExecutionContext()
        {
            Result = result,
            LastCount = result.Values.Count
        };

        Task t = Task.Factory.StartNew(() =>
            {
                foreach (var dataSlice in dataObjects)
                {
                   Task.Factory.StartNew(() =>
                   {
                       // Do Some Work
                   }, TaskCreationOptions.AttachedToParent);
                }
            });

        ctx.ParentTask = t;


        Task monitor = Task.Factory.StartNew( () =>
            {
                ctx.LastCount = ctx.Result.Values.Count;

            }, TaskCreationOptions.LongRunning);
我的问题,或者可能的问题是,如果我强制我的监视器任务等待(通过SpinWait或Sleep),它可能会锁定在它上面创建的部分任务吗?我需要监视器不时检查状态,但我不希望它的等待条件杀死另一个需要运行的任务

编辑:

因此,我发现了一个有趣的方法,它与Hans在下面的评论中所建议的非常相似。它分为两部分。一个任务在中间发生多次,一个完成任务完成最后的清理。仍在测试中,但看起来很有希望

下面是它的样子:

            Task t = new Task(() =>
            {
                int i = 0;
                for (int j = 0; j < 200; j++)
                {

                    foreach (var session in sessions)
                    {
                        Task work = action.Invoke(SomeParameter);
                        if (i == 50 || i == 0)
                        {
                            work.ContinueWith(task => Task.Factory.StartNew(UpdateAction));
                            i = 1;
                        }
                        else
                        {
                            i++;
                        }
                    }
                }
            });

        ctx.ParentTask = t;

        t.ContinueWith(CompletionAction => Task.Factory.StartNew(() => CompleteExecution(SomeParameter)));

        t.Start();
Task t=新任务(()=>
{
int i=0;
对于(int j=0;j<200;j++)
{
foreach(会话中的var会话)
{
任务工时=action.Invoke(SomeParameter);
如果(i==50 | | i==0)
{
work.ContinueWith(task=>task.Factory.StartNew(UpdateAction));
i=1;
}
其他的
{
i++;
}
}
}
});
ctx.ParentTask=t;
t、 继续(CompletionAction=>Task.Factory.StartNew(()=>CompleteExecution(SomeParameter)));
t、 Start();

避免监控,采用“不要打电话给我们,我们会打电话给你”的原则。使用TaskScheduler.FromCurrentSynchronizationContext()继续执行在UI线程上运行代码的任务。与BackgroundWorker.ReportProgress()的想法相同。鉴于需要使用进度更新UI,如果可以,只需使用BackgroundWorker即可。:)我在这方面不是很强,但我会研究TPL Parallel.ForEach而不是那个ForEach,这样TPL就可以做它所做的事情。Backgroundworker将只使用一个线程来处理所有数据对象,而任务将并行处理它们。TPL使Backgroundworker变得过时,特别是在.NET 4.5中,使用IProgress接口或async/awaitOk可以轻松处理UI更新,唯一的问题是我的“UI”是不同机器上的不同进程。三层架构,这是在中间层运行。