传递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中启动一个新任务更好?

传递Task作为方法参数是否安全?

这是不安全的,因为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);
}

我认为它们具有相同的底层结构。

这会导致死锁。我怀疑你的代码也是如此。所以我认为这是不安全的