V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
penll
V2EX  ›  C#

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

  •  1
     
  •   penll · 2021-07-30 15:43:29 +08:00 · 1584 次点击
    这是一个创建于 972 天前的主题,其中的信息可能已经有所发展或是发生改变。
     // 做一件无需等待的事情
     // 如一个接口完成一件操作
     // 需要额外更新的操作放到此异步方法内
     // 问:额外更新的是同步操作,是否有必要做成异步形式
     // 如果做成这样,那么此方式是否影响到性能,比如开辟过多的线程?
    private static aysnc void DoSomething()
    { 
    	//是否需要包在 Task.Run 内
     	await Task.Run(() =>
     	{
     		// 以下几种可能是同步处理代码的情况
     		// 1 、普通处理只需 CPU 计算
        	// 2 、需要数据库读写等 I/O 操作
     	}
     }
    
    第 1 条附言  ·  2021-08-02 09:50:54 +08:00
    谢谢各位啦
    3 条回复    2021-07-31 08:27:44 +08:00
    Zhuzhuchenyan
        1
    Zhuzhuchenyan  
       2021-07-30 18:51:51 +08:00   ❤️ 1
    - 需要额外更新的操作放到此异步方法内,额外更新的是同步操作

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

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

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

    2 、需要数据库读写等 I/O 操作
    此处建议直接找原生支持 Task 的异步方法的库
    ljchengx
        2
    ljchengx  
       2021-07-31 08:27:00 +08:00   ❤️ 1
    之前处理过,大批量的数据同步操作,也用到了 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
        3
    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 + "个");
    }
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5470 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 09:07 · PVG 17:07 · LAX 02:07 · JFK 05:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.