mvc中,使用异步方法的问题。

ms__csharp 2018-02-07 03:49:24

public class HomeController : Controller
{
public async Task<JsonResult> IndexData1()
{
var Data = new {
status = 100,
html =await new BusinessLayer().GetCSDNData_1()
//html =await new BusinessLayer().GetCSDNData_2() //这里的GetCSDNData_1、GetCSDNData_2使用哪种更合理?
};
return Json(Data);
}
public async Task<int> IndexData2()
{
//这里直接在mvc的action中使用Task.Run产生后台线程,这样合理吗?
var taskData =Task.Run<int>(() =>
{
return 100;//假设这里有一个比较耗时的操作
});
return await taskData;
}

}

public class BusinessLayer
{
/// <summary>
/// 在这里不使用async,不会产生后台线程
/// </summary>
/// <returns></returns>
public Task<string> GetCSDNData_1()
{
var url = $"https://www.csdn.net/";
var html = new Tools().GetWebTest(url);
return html;
}
/// <summary>
/// 在await后,产生后台线程
/// </summary>
/// <returns></returns>
public async Task<string> GetCSDNData_2()
{
var url = $"https://www.csdn.net/";
var html =await new Tools().GetWebTest(url);
return html;
}
}

public class Tools
{
public async Task<string> GetWebTest(string url)
{
WebClient client = new WebClient();
var html=await client.DownloadStringTaskAsync(url);
return html;
}

}


==================
1、GetCSDNData_1方法,只是返回Task<string>,而GetCSDNData_2是异步方法,都调用GetWebTest,哪种方法比较合理?
2、在控制器的Action中,直接使用Task.Run产生新的后台线程,这样合理吗?

...全文
727 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdfgrtyu 2018-02-08
  • 打赏
  • 举报
回复
这写的是什么啊,看来你对异步挺有研究的,可以一起探讨探讨啊
秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
async/await似乎正好解决这种问题 还可以用委托实现你的问题,begininvoke和endinvoke,使用回调函数,但写法复杂,不推荐
  • 打赏
  • 举报
回复
task也是会产生死锁和竞争问题的…… 另外增加负荷这词不对,多线程本来就是要增加处理量(或处理速度),这本来就会增加服务器的各项使用,而async await其实是为了降低多线程的使用难度而产生的 缺点的话不知道该怎么描述……
秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
建议lz就按照GetCSDNData_1方式做 用Task.Run,需要等待GetWebTest返回结果,例如用ContinueWith,这样会阻塞主线程 或者不等待,还可以轮询检查task是否执行完,这样会增加系统的负担
引用 9 楼 ms__csharp 的回复:
如果用Task.Run包装所有方法,程序也能正常执行,还能减少阻塞,增加吞吐量。 那么这么做有,除了会增加一下机器的负荷、改程序麻烦,那么从程序运行上看还有哪些缺点呢?
ms__csharp 2018-02-07
  • 打赏
  • 举报
回复
引用 8 楼 starfd 的回复:
Task本来就是线程,不是不用async就不产生线程…… 你的理解根本就是错的,当然也不能一棍子说task必定是线程,毕竟Task.FromResult这些其实是没开线程
除了避免死锁外,如果用Task.Run包装所有方法,程序也能正常执行,还能减少阻塞,增加吞吐量。 那么这么做有,除了会增加一下机器的负荷、改程序麻烦,那么从程序运行上看还有哪些缺点呢?
  • 打赏
  • 举报
回复
Task本来就是线程,不是不用async就不产生线程…… 你的理解根本就是错的,当然也不能一棍子说task必定是线程,毕竟Task.FromResult这些其实是没开线程
ms__csharp 2018-02-07
  • 打赏
  • 举报
回复
如果用Task.Run包装所有方法,程序也能正常执行,还能减少阻塞,增加吞吐量。 那么这么做有,除了会增加一下机器的负荷、改程序麻烦,那么从程序运行上看还有哪些缺点呢?
秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
再没有别的功能,只是等待请求数据,GetCSDNData_2中,async/await是多余的,要有作用,就是把自己给绕晕
秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
把我绕糊涂了! 用GetCSDNData_1就可以了,无需再async/await了 既然GetWebTest是异步的,完全可以一步到位,看例子(为了方便测试,我把类剥离了)

private async void button1_Click(object sender, EventArgs e)
{
    string r = await GetWebTest("https://www.baidu.com/");
    MessageBox.Show(r);

}

public async Task<string> GetWebTest(string url)
{
    WebClient client = new WebClient();
    var html = await client.DownloadStringTaskAsync(url);
    return html;
}

秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
嗯,看错了,GetWebTest也是异步的,我没注意这个,以为是普通非异步方法
ms__csharp 2018-02-07
  • 打赏
  • 举报
回复
引用 2 楼 From_TaiWan 的回复:
1、
public Task<string> GetCSDNData_1()
{
var url = $"https://www.csdn.net/";
var html = new Tools().GetWebTest(url);
return html;
}
==>
编译应该通不过。用GetCSDNData_2

2、可以直接用。代码多的话,分开写好维护罢了

GetCSDNData_1() 是可以正常编译运行的。
ms__csharp 2018-02-07
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
没有什么合理不合理的吧,你以为没有Task.Run,直接async await就没这个过程了?
await这里用到的状态机一直没搞清楚。 特别是Task.Run,如果可以随意使用,那么任何一个方法,放到Task.Run中,就可以变成异步调用了,那么又要把调用方法改为异步。如果是正常的,那么好像很少见到这样的用法,如果不是正常的,又为什么?
秋的红果实 2018-02-07
  • 打赏
  • 举报
回复
1、 public Task<string> GetCSDNData_1() { var url = $"https://www.csdn.net/"; var html = new Tools().GetWebTest(url); return html; } ==> 编译应该通不过。用GetCSDNData_2 2、可以直接用。代码多的话,分开写好维护罢了
  • 打赏
  • 举报
回复
没有什么合理不合理的吧,你以为没有Task.Run,直接async await就没这个过程了?

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧