传递Task作为方法参数是否安全?
本文关键字:是否 安全 参数 方法 Task 传递 | 更新日期: 2023-09-27 18:11:45
考虑以下代码:
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中启动一个新任务更好?
这是不安全的,因为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
不修改正在调用它的任务。创建一个新任务
我已经把你的代码简化为这个例子:
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);
}
我认为它们具有相同的底层结构。
这会导致死锁。我怀疑你的代码也是如此。所以我认为这是不安全的