c#相当于使用某个参数重新启动Task

时间:2014-02-25 12:52:34

标签: c# parallel-processing task

这里的主要思想是从某处获取一些数据,当它被取出时开始写入它,然后准备下一批要写入的数据,同时等待前一次写入完成。

我知道Task无法重新启动或重用(也不应该),尽管我正在尝试找到一种方法来执行此类操作:

//The "WriteTargetData" method should take the "data" variable 
//created in the loop below as a parameter
//WriteData basically do a shedload of mongodb upserts in a separate thread,
//it takes approx. 20-30 secs to run
var task = new Task(() => WriteData(somedata));

//GetData also takes some time.
foreach (var data in queries.Select(GetData))
{
    if (task.Status != TaskStatus.Running)
    {
        //start task with "data" as a parameter
        //continue the loop to prepare the next batch of data to be written
    }
    else
    {
        //wait for task to be completed
        //"restart" task
        //continue the loop to prepare the next batch of data to be written
    }
}

任何建议都表示赞赏!谢谢。我不一定要使用Task,我认为这可能是要走的路。

4 个答案:

答案 0 :(得分:1)

这可能过度简化了您的要求,但只是“等待”上一个任务为您完成工作?您可以使用Task.WaitAnyTask.WaitAll等待之前的操作完成。

伪代码:

    // Method that makes calls to fetch and write data.
    public async Task DoStuff()
    {
        Task currTask = null;

        object somedata = await FetchData();

        while (somedata != null)
        {
            // Wait for previous task.
            if (currTask != null)
                Task.WaitAny(currTask);

            currTask = WriteData(somedata);

            somedata = await FetchData();
        }
    }

    // Whatever method fetches data.
    public Task<object> FetchData()
    {
        var data = new object();

        return Task.FromResult(data);
    }

    // Whatever method writes data.
    public Task WriteData(object somedata)
    {
        return Task.Factory.StartNew(() => { /* write data */});
    }

答案 1 :(得分:0)

Task类不是为重新启动而设计的。所以你需要创建一个新任务并使用相同的参数运行主体。接下来,我看不到你在哪里用WriteData函数开始它的任务。这将属性消除if (task.Status != TaskStatus.Running)的调用AFAIK只有类TaskThread,其中任务只是将使用TaskSchedulerWriteData安排的操作的抽象。在不同的线程中执行(当我们谈论Common task Scheduler时,你调用TaskFactory.Scheduler时得到的那个)和线程数等于处理器内核的数量。

给你的商业应用程序。你为什么要等{{1}}的执行?收集所有数据并将它们提交到一个大的Write中会不会容易得多?

答案 2 :(得分:0)

之类的东西?

      public void Do()
        {
            var task = StartTask(500);
            var array = new[] {1000, 2000, 3000};

        foreach (var data in array)
        {
            if (task.IsCompleted)
            {
                task = StartTask(data);
            }
            else
            {
                task.Wait();
                task = StartTask(data);
            }
        }
    }

    private Task StartTask(int data)
    {
        var task = new Task(DoSmth, data);
        task.Start();
        return task;
    }

    private void DoSmth(object time)
    {
        Thread.Sleep((int) time);
    }

答案 3 :(得分:0)

您可以使用线程和AutoResetEvent。对于程序中的几个不同的线程,我有这样的代码:

这些是属于主程序的变量声明。

public AutoResetEvent StartTask = new AutoResetEvent(false);
public bool IsStopping = false;
public Thread RepeatingTaskThread;

初始化代码中的某处:

RepeatingTaskThread = new Thread( new ThreadStart( RepeatingTaskProcessor ) ) { IsBackground = true; };
RepeatingTaskThread.Start();

然后运行重复任务的方法看起来像这样:

private void RepeatingTaskProcessor() {
    // Keep looping until the program is going down.
    while (!IsStopping) {
        // Wait to receive notification that there's something to process.
        StartTask.WaitOne();

        // Exit if the program is stopping now.
        if (IsStopping) return;

        // Execute your task
        PerformTask();
    }
}

如果要运行多个不同的任务,可以添加一个变量来指示要处理哪个任务,并修改PerformTask中的逻辑以选择要运行的任务。

我知道它没有使用Task类,但是不仅有一种方法可以使猫和猫皮肤接触。这将有效。