首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Task<Task>在C#非法?

Task<Task>在C#非法?
EN

Stack Overflow用户
提问于 2017-03-27 14:15:34
回答 3查看 240关注 0票数 1

此代码在中给出VS2015中的编译时错误

错误'System.Threading.Tasks.Task'. CS0266不能隐式地将'System.Threading.Tasks.Task‘类型转换为存在显式转换(是否缺少强制转换?)

更新1:在任务之后扩展了代码,而不是Task<任务>。

代码语言:javascript
复制
        int i = 0;

        Task<int> test = Task.Run( () => {
            return i;
        } );

        i = test.Result;

        Task t = Task.Run( () => { } );

        Task<Task> test2 = Task.Run( () => {
            return t;
        } );

        t = test2.Result;

我做错了什么?

更新2: --这段代码给出了一个警告(我不想要警告,也不需要禁止实用程序)

警告CS1998这个异步方法缺少“等待”操作符,并且将同步运行。考虑使用“等待”操作符等待非阻塞的API调用,或“等待Task.Run(.)”在后台线程上执行CPU绑定工作。

代码语言:javascript
复制
        int i = 0;

        Task<int> test = Task.Run( () => {
            return i;
        } );

        i = test.Result;

        Task t = Task.Run( () => { } ); 

        Task<Task> test2 = Task.Run( async () => {
            return t;
        } );

        t = test2.Result;

更新3:

所有坚持Task test2的人。

  1. StartAndReturnSecondTaskAsync必须返回第二个任务(执行longOperation2)
  2. StartAndReturnSecondTaskAsync必须是async,也就是说UI不能在longOperation1期间阻塞。 公共静态异步任务StartAndReturnSecondTaskAsync() {任务t=等待Task.Run( () => {返回StartAndReturnSecondTask ();} );返回t;}公共静态任务StartAndReturnSecondTask() { var importantData = longOperation1();返回Task.Run( () => { longOperation2( importantData );} );}任务第二=等待StartAndReturnSecondTaskAsync();
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-27 14:26:21

这是一种非常常见的操作,但使用Task.Run执行一些异步操作,如果使用旧的方法StartNew,它将执行您所期望的操作,即调度线程池线程来启动异步操作,并告诉您异步操作何时结束。

然而,这根本不是人们真正想要的。他们想知道Task.RUn中调用的异步操作何时结束。正因为如此,Task.Run将对任何Task<Task> that would be returned, so that what you're really seeing is the inner任务展开。

如果您确实只想让线程池线程启动任务,并且只知道它何时已经启动,那么您可以使用Task.Factory.StartNew,它不会代表您展开Task<Task>

票数 2
EN

Stack Overflow用户

发布于 2017-03-27 14:19:35

Task<Task>很常见,而且常常是一个问题(如果我们错误地等待/等待错误的外部任务):

代码语言:javascript
复制
  int i = 0;

  Task<int> test = Task.Run(() => {
    return i;
  });

  Task t = Task.Run(() => {
  });

  // please, notice "async"
  Task<Task> test2 = Task.Run(async () => { // <- async: let insist on Task<Task>...
    return t;
  });

甚至有一个Task<Task>的扩展方法

代码语言:javascript
复制
  Task backToTask = test2.Unwrap();

在你的情况下你想

代码语言:javascript
复制
  Task test2 = Task.Run(() => {
    return t;
  });

因为Task.Run为你打电话给Unwrap()

票数 2
EN

Stack Overflow用户

发布于 2017-03-27 14:35:09

一种简单的解决方案,不涉及太多细节:

将起作用的守则是:

代码语言:javascript
复制
int i = 0;
Task<int> test = Task.Run(() =>
{
    return i;
});
Task t = Task.Run(() => { });
Task test2 = Task.Run(() =>
{
    return t;
});

如果使用其他使用await的可能方法,则需要将上下文async设置为:

代码语言:javascript
复制
public async Task DoesTheThreadedOperations()
{
// Your code in question and other code
}

根据您的更新3

代码语言:javascript
复制
public static async Task StartAndReturnSecondTaskAsync()
{
    await Task.Run(() =>
    {
        return StartAndReturnSecondTask();
    });
}

public static Task StartAndReturnSecondTask()
{
    System.Threading.Thread.Sleep(5000);
    return Task.Run(() =>
    {
        System.Threading.Thread.Sleep(10000);
    });
}

我用睡眠来模仿你的长时间手术。我希望您不一定要使用Task<Task>。这应该给你足够的推力来攻击你的场景。您可以进一步改进它,使这两个操作具有两个不同的线程,并将结果从一个线程传递给另一个线程,以获得确切的结果,等待所需的线程,然后运行另一个较长的任务,而无需等待。也就是说,从主方法调用两个方法,一个等待,另一个不调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43048866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档