这里的主要思想是从某处获取一些数据,当它被取出时开始写入它,然后准备下一批要写入的数据,同时等待前一次写入完成。
我知道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
,我认为这可能是要走的路。
答案 0 :(得分:1)
这可能过度简化了您的要求,但只是“等待”上一个任务为您完成工作?您可以使用Task.WaitAny和Task.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只有类Task
和Thread
,其中任务只是将使用TaskScheduler
和WriteData
安排的操作的抽象。在不同的线程中执行(当我们谈论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
类,但是不仅有一种方法可以使猫和猫皮肤接触。这将有效。