异步运行控制台任务

时间:2013-08-25 14:46:03

标签: c# .net

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



namespace NewTask
{
    class Program
    {
        static void Main(string[] args)
        {
            NewTask.Combine taskcombine = new NewTask.Combine();
            ProfileClient profilesws = new ProfileClient();
            var profileRecords = profilesws.GetAllProfiles();
            foreach (var profile in profileRecords.ProfileRecords)
            {
                var testProfile = new NewTask.Profile();
                testProfile.Id = profile.Id;
                testProfile.Name = profile.Name;


                var result = taskcombine.TestProfile(testProfile);

            }


            profilesws.Close();
            taskcombine.Close();
        }
    }
}

我想要一种运行此异步的方法。我想点击ruslt,一旦它通过所有记录到结果我希望它结束​​任务。这将是一个consol应用程序,一旦结果填充了所需的记录,我希望它能异步关闭应用程序。

1 个答案:

答案 0 :(得分:1)

如果TestProfile的{​​{1}}版本返回任务,则代码将为

TestProfileAsync

如果该函数没有异步版本,则需要将其包装在您自己的任务中。

class Program
{
    static void Main(string[] args)
    {
        NewTask.Combine taskcombine = new NewTask.Combine();
        ProfileClient profilesws = new ProfileClient();
        var profileRecords = profilesws.GetAllProfiles();

        var tasks = new List<Task<ResultClass>>();

        foreach (var profile in profileRecords.ProfileRecords)
        {
            var testProfile = new NewTask.Profile();
            testProfile.Id = profile.Id;
            testProfile.Name = profile.Name;

            tasks.Add(taskcombine.TestProfileAsync(testProfile))
        }

        int completedIndex = Task.WaitAny(tasks.ToArray());

        var result = tasks[completedIndex].Result;

        profilesws.Close();
        taskcombine.Close();
    }
}

这是假设tasks.Add(Task<ResultClass>.Factory.Start(() => taskcombine.TestProfile(testProfile))); 是线程安全的。如果它不是线程安全的,你需要解释更多taskcombine.TestProfile的作用,以及你是否可以创建它的多个实例

taskcombine.TestProfile

编辑:您可以做的另一个调整就是使用cancellation token,所以如果您在某些任务开始之前已经有了结果,那么它们将无法启动。

首先,使用具有签名tasks.Add(Task<ResultClass>.Factory.Start(() => { NewTask.Combine taskcombine = new NewTask.Combine(); //Move the declaration inside the task so a new Combine gets created per task. return taskcombine.TestProfile(testProfile); }));

的异步版TestProfileAsync的梦想解决方案
Task<ResultClass> TestProfileAsync(NewTask.Profile a, CancllationToken token)

如果您无法访问异步版本,则此处是带有任务的4.5版本代码

class Program
{
    static void Main(string[] args)
    {
        NewTask.Combine taskcombine = new NewTask.Combine();
        ProfileClient profilesws = new ProfileClient();
        var profileRecords = profilesws.GetAllProfiles();

        var tasks = new List<Task<ResultClass>>();
        var cts = new CancellationTokenSource();
        var token = cts.Token;            

        foreach (var profile in profileRecords.ProfileRecords)
        {
            var testProfile = new NewTask.Profile();
            testProfile.Id = profile.Id;
            testProfile.Name = profile.Name;

            tasks.Add(taskcombine.TestProfileAsync(testProfile, token))
        }

        int completedIndex = Task.WaitAny(tasks.ToArray());

        //This should stop any tasks before they even start.
        cts.Cancel();

        var result = tasks[completedIndex].Result;

        profilesws.Close();
        taskcombine.Close();
    }
}