【问题标题】:Running multiple C# Task Async运行多个 C# 任务异步
【发布时间】:2011-04-15 02:00:09
【问题描述】:

您好,通常我会使用 Background Worker 执行此操作,但我想使用 C# Task 执行此操作,只是为了更好地理解 Task。

问题是我有一个具有以下属性的类

    private int _number1;
    public int Number1
    {
        get { return _number1; }
        set { _number1 = value; OnPropertyChanged("Number1");}
    }

    private int _number2;
    public int Number2
    {
        get { return _number2; }
        set { _number2 = value; OnPropertyChanged("Number2");}
    }

请注意,我使用的是 INotifyPropertyChanged。

Number1 = Task<int>.Factory.StartNew(() => GenerateResult()).Result;
Number2 = Task<int>.Factory.StartNew(() => GenerateResult2()).Result;

GenerateResult 和 GenerateResult2 只是哑方法,它们休眠然后返回一个数字。

如何使这项工作异步?从现在开始,GenerateResult2() 在 GenerateResult() 完成时首先被调用。

我需要它能够异步工作,因为我不知道每项任务何时完成,甚至不知道它是否会完成。

【问题讨论】:

    标签: c# .net multithreading c#-4.0


    【解决方案1】:

    当您获得Result 属性时,您实际上是在等待任务完成。它将在后台线程上执行,但您正在主线程中等待完成,然后再启动下一个线程。

    详情请参阅MSDN doc

    您应该能够只从后台线程分配您的属性:

    Task<int>.Factory.StartNew(() => Number1 = GenerateResult());
    

    WPF 数据绑定将take care of marshalling PropertyChanged 事件发送到正确的调度程序线程。

    【讨论】:

    • 非常感谢 Isak Savo 工作完美且易于阅读 :-) 比 Backgroundworkers 容易得多
    • 不确定任何任务都会一直在工作线程上执行。 Result 只是阻塞调用它的线程,直到它准备好输出数据或设置异常。
    • 谢谢,我有一个调试行正在调用 .Result 所以我可以做一个快速测试,它破坏了异步:O
    【解决方案2】:

    我检查了这个:Task Parallelism (Task Parallel Library),它指出当使用System.Threading.Tasks.Task&lt;TResult&gt; 时,任务异步运行并且可以按任何顺序完成。 如果在计算完成之前访问 Result,该属性将阻塞线程,直到值可用。

    我认为这意味着如果您在 .Result 获得值之前访问它,就像您在示例代码中所做的那样,您必须先等待它完成。

    这确实有意义,因为在任务完成之前不会填充 Result 属性。

    【讨论】:

    • 没有看到 Isak Savo 的回答已经指出访问 Result 将等待任务完成。
    【解决方案3】:
    Task<int>.Factory.StartNew(() => GenerateResult2()).ContinueWith(() => GenerateResult());
    

    【讨论】:

    • 除非我弄错了,否则这与 OP 代码的语义完全相同——第二个任务在第一个任务完成之前不会开始。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多