【问题标题】:Task<T> doesn't respond in WebApi, but returning non Task worksTask<T> 在 WebApi 中没有响应,但返回非 Task 有效
【发布时间】:2014-05-19 23:51:46
【问题描述】:

我有一个不会向浏览器返回响应的方法,我已经尝试使用浏览器本身和 chrome 扩展 POSTMan。

    [AllowAnonymous]
    [Route("getNotifications")]
    [AcceptVerbs("Get", "Post")]
    public Task<List<UserNotifications>> GetNotifications()
    {
        Task<List<UserNotifications>> userNotList = new Task<List<UserNotifications>>(() => new List<UserNotifications>{
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 1",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 1"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 2",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 2"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 3",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 3"
            }
        });
        return userNotList;
    }

但是,如果我将方法更改为不返回类型 Task...

[AllowAnonymous]
[Route("getNotifications")]
[Authorize]
[AcceptVerbs("Get", "Post")]
public List<UserNotifications> GetNotifications()
{
    var newstring = "";
    List<UserNotifications> userNotList = new List<UserNotifications>{
        new UserNotifications()
        {
            UserId = new Guid(),
            MessageText = "Message 1",
            MessageTime = DateTime.Now,
            Status = true,
            Subject = "new message 1"
        },
        new UserNotifications()
        {
            UserId = new Guid(),
            MessageText = "Message 2",
            MessageTime = DateTime.Now,
            Status = true,
            Subject = "new message 2"
        },
        new UserNotifications()
        {
            UserId = new Guid(),
            MessageText = "Message 3",
            MessageTime = DateTime.Now,
            Status = true,
            Subject = "new message 3"
        }
    };

    return userNotList;
}

我每次都得到以下回报

[
    {
        "userId": "00000000-0000-0000-0000-000000000000",
        "subject": "new message 1",
        "messageText": "Message 1",
        "messageTime": "2014-05-19T11:03:32.707957-04:00",
        "status": true
    },
    {
        "userId": "00000000-0000-0000-0000-000000000000",
        "subject": "new message 2",
        "messageText": "Message 2",
        "messageTime": "2014-05-19T11:03:32.707957-04:00",
        "status": true
    },
    {
        "userId": "00000000-0000-0000-0000-000000000000",
        "subject": "new message 3",
        "messageText": "Message 3",
        "messageTime": "2014-05-19T11:03:32.707957-04:00",
        "status": true
    }
]

为什么当我使用任务时,在直接对 webapi 服务进行测试调用时,浏览器没有返回任何内容?

编辑 1

改变了方法...由于某种原因仍然坐着旋转它的轮子

    [AllowAnonymous]
    [Route("getNotifications")]
    [AcceptVerbs("Get", "Post")]
    public async Task<List<UserNotifications>> GetNotifications()
    {
        Task<List<UserNotifications>> userNotList = new Task<List<UserNotifications>>(() => new List<UserNotifications>{
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 1",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 1"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 2",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 2"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 3",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 3"
            }
        });
        return await userNotList;
    }

但是当我把它改成这个时......

    [AllowAnonymous]
    [Route("getNotifications")]
    [AcceptVerbs("Get", "Post")]
    public Task<List<UserNotifications>> GetNotifications()
    {
        var newstring = "";
        List<UserNotifications> userNotList = new List<UserNotifications>{
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 1",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 1"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 2",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 2"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 3",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 3"
            }
        };

        return Task.FromResult(userNotList);
    }

它返回的结果很好......任何人都可以澄清这些方法之间的区别是什么。我正在冒险进入 Task、asnyc 和 await 领域,但我仍然需要能够使用 POSTMan 之类的工具直接测试对 webapi 的调用。

编辑 2 以下两种变体都有效...

    [AllowAnonymous]
    [Route("getNotifications")]
    [AcceptVerbs("Get", "Post")]
    public Task<List<UserNotifications>> GetNotifications()
    {
        var userNotList = Task.Run(
                () => new List<UserNotifications>{
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 1",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 1"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 2",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 2"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 3",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 3"
            }
        });

        return userNotList;
    }

    [AllowAnonymous]
    [Route("getNotifications")]
    [AcceptVerbs("Get", "Post")]
    public async Task<List<UserNotifications>> GetNotifications()
    {
        var userNotList = Task.Run(
                () => new List<UserNotifications>{
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 1",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 1"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 2",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 2"
            },
            new UserNotifications()
            {
                UserId = new Guid(),
                MessageText = "Message 3",
                MessageTime = DateTime.Now,
                Status = true,
                Subject = "new message 3"
            }
        });

        return await userNotList;
    }

【问题讨论】:

  • 试试“return await userNotList;”
  • ... 并且可能使用async 方法。那么它应该可以工作了。
  • 你到底想做什么?如果您有(同步)数据要返回,只需同步返回(不包含在任务中)。

标签: c# task asp.net-web-api


【解决方案1】:

您已经创建任务,但还没有真正开始,请尝试替换您的任务构造函数:

Task<List<UserNotifications>> userNotList = new Task<List<UserNotifications>>(...

以下内容:

var userNotList = Task<List<UserNotifications>>.Run(
                    () => new List<UserNotifications>{...});

更新

  1. 添加async/await 的编辑示例的问题是相同的,您创建一个知道该做什么的对象 ~ Task,但实际上您并没有告诉开始做这项工作 ~ Run 方法。
  2. 在使用Task.FromResult(userNotList) 的第二个示例中,您已经有了结果列表,只需将其包装到一个已完成 Task 中并返回它。

有关此主题的更多信息,我强烈建议您阅读Task-based Asynchronous Pattern

【讨论】:

  • 技术上正确,但 Task.Run 不应在 ASP.NET 上使用。
  • 用 Google 搜索 task.run asp.net 并找到您的博客文章 - 有趣的阅读,谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2018-10-13
  • 2016-09-23
相关资源
最近更新 更多