Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理异步线程_C#_.net_Multithreading_Asynchronous - Fatal编程技术网

C# 处理异步线程

C# 处理异步线程,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,我(认为我)理解线程和任务之间的区别 线程允许我们并行地做多件事情(它们受CPU限制) 异步任务在某些I/O工作完成时释放处理器时间(它们是I/O绑定的) 现在,假设我想并行执行多个异步任务。例如,我想同时下载一个分页响应的多个页面。或者,我想将新数据写入两个不同的数据库。处理线程的正确方法是什么?它们是否应该异步并等待?或者异步操作可以就在线程内部吗?错误处理的最佳实践是什么 我曾尝试创建自己的实用程序方法来启动一个新的异步线程,但我有一种感觉,它可能会出现可怕的错误 public sta

我(认为我)理解线程和任务之间的区别

  • 线程允许我们并行地做多件事情(它们受CPU限制)
  • 异步任务在某些I/O工作完成时释放处理器时间(它们是I/O绑定的)
现在,假设我想并行执行多个异步任务。例如,我想同时下载一个分页响应的多个页面。或者,我想将新数据写入两个不同的数据库。处理线程的正确方法是什么?它们是否应该异步并等待?或者异步操作可以就在线程内部吗?错误处理的最佳实践是什么

我曾尝试创建自己的实用程序方法来启动一个新的异步线程,但我有一种感觉,它可能会出现可怕的错误

public static Task<Thread> RunInThreadAsync<T>(T actionParam, Func<T, Task> asyncAction)
{
    var thread = new Thread(async () => await asyncAction(actionParam));
    thread.Start();
    return thread;
}
公共静态任务RunInThreadAsync(T actionParam,Func asyncAction)
{
var-thread=新线程(async()=>等待异步操作(actionParam));
thread.Start();
返回线程;
}
这样行吗?或者该方法应该是
公共静态异步任务
?如果是,应该等待什么?没有
线程。StartAsync()
。或者我应该使用
Task.Run

注意:使用
等待任务。当所有的
或类似方法没有明确的新线程时,我不能选择。“worker”线程在后台运行(以避免阻塞主线程),稍后由系统中的其他服务处理

我(认为我)理解线程和任务之间的区别

这里缺少一个重要的概念:并发性。并发性是指一次做不止一件事。这与“并行”不同,大多数开发人员使用“并行”一词来表示“使用线程一次做多件事”。因此,并行是并发的一种形式,异步是并发的另一种形式

现在,假设我想并行执行多个异步任务

问题是:混合两种形式的并发。您真正想要做的是同时执行多个异步任务。实现这一点的方法是通过
Task.whalll

在没有显式新线程的情况下使用wait Task.WhenAll或类似方法对我来说不是一个选项。“worker”线程在后台运行(以避免阻塞主线程),稍后由系统中的其他服务处理

这个论点毫无意义。异步代码不会阻止主线程,因为它是异步的。不需要显式线程


如果出于某种未知的原因,您确实需要一个后台线程,那么只需将代码包装在
任务中。运行
<代码>线程
只能用于COM互操作;
Thread
的任何其他用法在编写后即为遗留代码。

System.Threading.Thread
自1.1版以来一直在.NET中。它允许您控制应用程序中的多个工作线程。这只使用一个CPU核心

任务并行库(TPL)引入了通过
async
任务或
System.Threading.Tasks.Task
利用计算机上多个内核的能力

对于您的“多重下载器”场景,我的方法是创建一个新的
CancellationTokenSource
,它允许我取消任务。我将开始创建我的
任务
,并启动它们。您可以使用
Task.WaitAll()
坐着等待

您应该知道,可以使用
ContinueWith()
方法按顺序将任务链接在一起

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
async class Program
{
    static bool DownloadFile (string path)
    {
        // Do something here. long running task.

        // check for cancellation -> Task.Factory.CancellationToken.IsCancellationRequested

        return true;
    }
    static async void Main(string[] args)
    {
        var paths = new[] { "Somepaths", "to the files youwant", "to download" };
        List<Task<bool>> results = new List<Task<bool>>();
        var cts = new System.Threading.CancellationTokenSource();

        foreach(var path in paths)
        {
            var task = new Task<bool>(_path => DownloadFile((string)_path), path, cts.Token);
            task.Start();
            results.Add(task);
        }

        // use cts.Cancel(); to cancel all associated tasks. 

        // Task.WhenAll() to do something when they are all done. 
        // Task.WaitAll( results.ToArray() );  // to sit and wait. 

        Console.WriteLine("Press <Enter> to quit.");
        var final = Console.ReadLine();
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间控制台EApp2
{
异步类程序
{
静态bool下载文件(字符串路径)
{
//在这里做点什么。长时间运行的任务。
//检查取消->Task.Factory.CancellationToken.IsCancellationRequested
返回true;
}
静态异步void Main(字符串[]args)
{
var path=new[]{“somepath”,“到您想要的文件”,“下载”};
列表结果=新列表();
var cts=new System.Threading.CancellationTokenSource();
foreach(路径中的变量路径)
{
var task=new task(_path=>DownloadFile((字符串)_path),path,cts.Token);
task.Start();
结果:添加(任务);
}
//使用cts.Cancel();取消所有关联的任务。
//Task.WhenAll()在完成任务后执行某项操作。
//Task.WaitAll(results.ToArray());//坐着等待。
控制台。WriteLine(“按退出”);
var final=Console.ReadLine();
}
}

}

ASNWER对我的情况没有什么帮助。我需要显式运行一个新线程。如果正在下载或运行DB查询,为什么需要一个新线程?因为这些线程在后台运行,稍后由其他服务在系统中处理。我给出了简化的示例,重点介绍线程的异步处理。也许我应该更明确地说线程是必要的。你仍然不需要线程在后台运行IO。