关于 C# 的异步使用方式疑问

2021-07-30 15:43:29 +08:00
 penll
 // 做一件无需等待的事情
 // 如一个接口完成一件操作
 // 需要额外更新的操作放到此异步方法内
 // 问:额外更新的是同步操作,是否有必要做成异步形式
 // 如果做成这样,那么此方式是否影响到性能,比如开辟过多的线程?
private static aysnc void DoSomething()
{ 
	//是否需要包在 Task.Run 内
 	await Task.Run(() =>
 	{
 		// 以下几种可能是同步处理代码的情况
 		// 1 、普通处理只需 CPU 计算
    	// 2 、需要数据库读写等 I/O 操作
 	}
 }
1614 次点击
所在节点    C#
3 条回复
Zhuzhuchenyan
2021-07-30 18:51:51 +08:00
- 需要额外更新的操作放到此异步方法内,额外更新的是同步操作

需要等待额外更新的操作结束才返回么?如果需要等待,那没必要用 Task.Run 再包一层

如果不需要等待,只是希望执行了以后就不管了,那么去掉 async,await,直接用 _ = Task.Run(...) 就可以了,Task.Run 会在线程池上执行操作,所以并不会开辟过多的线程。

---
另附,
1 、普通处理只需 CPU 计算
如果的确这个普通处理会耗费相对较多 CPU 时间,而期望调用函数尽快返回的话,用 Task.Run 是一个比较常见的方法

2 、需要数据库读写等 I/O 操作
此处建议直接找原生支持 Task 的异步方法的库
ljchengx
2021-07-31 08:27:00 +08:00
之前处理过,大批量的数据同步操作,也用到了 Task,写了两个例子 可以参考下,希望有帮助:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
class Program
{
public static bool _go = true;
public static int currentTeacherCount = 0;
public static int maxTask = 15;
public static object obj = new object();
static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
List<String> list = new List<string>();
list.Add("1");
list.Add("2");
list.Add("3");
list.Add("4");
foreach (var item in list)
{
tasks.Add(Task.Factory.StartNew(() =>
{
Log(item);
}).ContinueWith(t =>
{
lock (obj)
{
Interlocked.Increment(ref currentTeacherCount);
Console.WriteLine("第" + currentTeacherCount + "数据同步完成,共" + list.Count() + "数据需要处理");
}
}));
if (tasks.Count >= maxTask)
{
Task.WaitAny(tasks.ToArray());
tasks = tasks.Where(t => t.Status == TaskStatus.Running).ToList();
}
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine("所有线程结束!");
Console.ReadLine();
}
public static void Log(String str)
{
Console.WriteLine("开始处理第" + str + "个");
}
}
}
ljchengx
2021-07-31 08:27:44 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
class Program
{
public static bool _go = true;
public static int currentTeacherCount = 0;
public static int maxTask = 15;
public static object obj = new object();
public static bool _go_LogStastic = true; //阀门

//轮询的多线程

static void Main(string[] args)
{
while (_go)
{
if (_go_LogStastic)
{
_go_LogStastic = false;
var task = new Task(delegate()
{
Log("1");

});
task.Start();
task.ContinueWith(q =>
{
_go_LogStastic = true;
});
}
}
Console.WriteLine("所有线程结束!");
Console.ReadLine();
}
public static void Log(String str)
{
Console.WriteLine("开始处理第" + str + "个");
}
}
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/792719

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX