请考虑以下代码:
public class Program {
static void Main(string[] args) {
Generate();
}
static void Generate() {
Task t = null;
t = Task.Run(() => {
MyClass myClass = new MyClass();
myClass.ContinueTask(t);
});
Console.ReadLine();
}
}
public class MyClass {
public void ContinueTask(Task t) {
t.ContinueWith(x => {
Console.WriteLine("Continue here...");
});
}
}
将t作为参数传递是否安全,或者直接在MyClass中启动新任务是否更好?
答案 0 :(得分:1)
我已将代码缩减到此示例:
public Task<int> Parse()
{
Task<int> t = null;
t = Task.Run(() => this.Read(t));
return t;
}
public Task<int> Read(Task<int> t)
{
return t.ContinueWith(v => 42);
}
我认为它具有相同的基础结构。
这导致死锁。我怀疑你的代码也是如此。所以我觉得它不安全。
答案 1 :(得分:1)
这是不安全的,因为t
可能不会在使用它时指定。事实上,这是一场数据竞赛。
即使你修复了这将是糟糕的架构。为什么ContinueTask
需要知道它正在继续某些事情。这不是一个应该位于此处的问题。 ContinueTask
假设其前提已经完成,应该执行它的工作。
很难说出你想要完成的事情。对代码进行排序有什么问题:?
static async Task Generate() {
var t = Task.Run(() => {
//... other code ...
});
MyClass myClass = new MyClass();
await t;
myClass.ContinueTask();
Console.ReadLine();
}
await
非常适合测序任务。
重用Task对象
你是什么意思?任务无法重复使用。它不能运行两次。你ContinueWith
做的所有事情都在逻辑上等待先行者然后运行lambda。在这里,任务基本上是一个事件。
ContinueWith
不会修改正在调用的任务。它创造了一项新任务。