Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.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# 如何处理具有一些等待和一些cpu绑定操作的异步方法_C#_Async Await - Fatal编程技术网

C# 如何处理具有一些等待和一些cpu绑定操作的异步方法

C# 如何处理具有一些等待和一些cpu绑定操作的异步方法,c#,async-await,C#,Async Await,我仍然无法理解async/Wait。我试图弄清楚我是否需要将CPU密集型工作负载打包到一个任务中。有人能告诉我哪种方法更好吗 没有任务。运行: public async Task ProcessData() { //Get some data var httpClient = new HttpClient(); var response = await httpClient.GetAsync("myUrl"); string data = await respon

我仍然无法理解async/Wait。我试图弄清楚我是否需要将CPU密集型工作负载打包到一个任务中。有人能告诉我哪种方法更好吗

没有任务。运行:

public async Task ProcessData()
{
    //Get some data
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync("myUrl");
    string data = await response.Content.ReadAsStringAsync();

    //Calculate result
    string result = null;
    for (int i = 0; i < 10000000; i++)
    {
        //Do some CPU intensive work
    }

    //Save results
    using (var fs = new FileStream("myFile.txt", FileMode.Create))
    using (var writer = new StreamWriter(fs))
    {
        await writer.WriteLineAsync(result);
    }
}
public async Task ProcessData()
{
    //Get some data
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync("myUrl");
    string data = await response.Content.ReadAsStringAsync();

    //Calculate result
    string result = null;
    await Task.Run(() =>
    {
        for (int i = 0; i < 10000000; i++)
        {
            //Do some CPU intensive work
        }
    });

    //Save results
    using (var fs = new FileStream("myFile.txt", FileMode.Create))
    using (var writer = new StreamWriter(fs))
    {
        await writer.WriteLineAsync(result);
    }
}
public异步任务ProcessData()
{
//获取一些数据
var httpClient=新的httpClient();
var response=await-httpClient.GetAsync(“myUrl”);
字符串数据=wait response.Content.ReadAsStringAsync();
//计算结果
字符串结果=null;
对于(int i=0;i<10000000;i++)
{
//做一些CPU密集型的工作
}
//保存结果
使用(var fs=newfilestream(“myFile.txt”,FileMode.Create))
使用(var编写器=新的StreamWriter(fs))
{
等待writer.WriteLineAsync(结果);
}
}
使用任务。运行:

public async Task ProcessData()
{
    //Get some data
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync("myUrl");
    string data = await response.Content.ReadAsStringAsync();

    //Calculate result
    string result = null;
    for (int i = 0; i < 10000000; i++)
    {
        //Do some CPU intensive work
    }

    //Save results
    using (var fs = new FileStream("myFile.txt", FileMode.Create))
    using (var writer = new StreamWriter(fs))
    {
        await writer.WriteLineAsync(result);
    }
}
public async Task ProcessData()
{
    //Get some data
    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync("myUrl");
    string data = await response.Content.ReadAsStringAsync();

    //Calculate result
    string result = null;
    await Task.Run(() =>
    {
        for (int i = 0; i < 10000000; i++)
        {
            //Do some CPU intensive work
        }
    });

    //Save results
    using (var fs = new FileStream("myFile.txt", FileMode.Create))
    using (var writer = new StreamWriter(fs))
    {
        await writer.WriteLineAsync(result);
    }
}
public异步任务ProcessData()
{
//获取一些数据
var httpClient=新的httpClient();
var response=await-httpClient.GetAsync(“myUrl”);
字符串数据=wait response.Content.ReadAsStringAsync();
//计算结果
字符串结果=null;
等待任务。运行(()=>
{
对于(int i=0;i<10000000;i++)
{
//做一些CPU密集型的工作
}
});
//保存结果
使用(var fs=newfilestream(“myFile.txt”,FileMode.Create))
使用(var编写器=新的StreamWriter(fs))
{
等待writer.WriteLineAsync(结果);
}
}
我的直觉是不使用Task.Run,但在这种情况下,这是否意味着异步方法中的所有代码都将在单独的线程上执行?这意味着调用线程不会被中断,直到最后(文件流关闭,方法结束)

或者调用线程是否会被中断,并返回此方法以首先执行CPU密集型部分,然后返回到ProcessData()在后台为FileStream部分运行时所执行的操作

我希望这是清楚的


提前感谢

使用
异步
来完成CPU绑定的工作

为什么异步在这里有帮助

async和await是在需要响应时管理CPU工作的最佳实践

此时,在调度工作之后,您需要在当前线程上同时执行其他工作,或者您需要返回线程以便它可以执行其他事情

例如,通常您希望避免在UI线程/UI同步上下文中执行CPU受限的工作,因为最终可能会出现冻结/无响应的UI。在这种情况下,您可以选择使用
Task.Run
将工作安排到线程池中的下一个可用线程

另外,假设您的代码已经在线程池线程上,这并不意味着您永远不应该使用
Task.Run
,因为有充分的理由可以与CPU绑定的工作并行运行

例如,您想要执行一个计算,并且在等待结果时,您想要为其他内容调用远程API,以便在返回结果时可以将结果组合在一起

这真的取决于你的情况。但您可能需要注意的是,当您使用
async
进行CPU受限的工作时,上下文切换会产生很小的开销。话虽如此,请注意,在代码中会发生上下文切换

需要注意的是,使用async的成本很小,不建议使用async进行紧密循环。由您决定如何围绕这个新功能编写代码

如我的中所述,
async
方法与任何其他方法一样,直接在调用线程的堆栈上开始执行。当一个
wait
异步操作时,它将捕获一个“上下文”,“暂停”该方法,并返回给它的调用者。稍后,当“异步等待”(
wait
)完成时,该方法将在捕获的上下文上恢复

因此,这意味着:

这是否意味着异步方法中的所有代码都将在单独的线程上执行

。根本没有线程“执行”wait,因为无事可做。当
wait
完成时,该方法继续在捕获的上下文中执行。有时这意味着该方法被排队到一个消息队列中,最终将由原始调用线程运行(例如,UI应用程序就是这样工作的)。其他时候,这意味着该方法由任何可用的线程池线程运行(大多数其他应用程序都是这样工作的)

这意味着调用线程不会被中断,直到最后(文件流关闭,方法结束)?或者调用线程是否会被中断,并返回此方法以首先执行CPU密集型部分,然后返回到ProcessData()在后台为FileStream部分运行时所执行的操作

调用线程从不中断

工作的CPU限制部分将在
wait
点捕获的任何“上下文”上运行。这可以是原始线程,也可以是线程池线程,具体取决于上下文

那么,回到原来的问题:

有人能告诉我哪种方法更好吗


如果这是可以从不同上下文调用的代码,那么我建议不要使用
Task.Run
,但我建议记录该方法是否执行CPU限制的工作。这样,如果调用方从UI线程调用此方法,则它知道使用
任务。在调用它时运行
,以确保UI线程未被阻止。

可能有一个没有
任务的优雅解决方案。如果可以接受一些限制,请运行

...
//Get some data
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("myUrl").ConfigureAwait(false);
string data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

//Calculate result
...
如果之前至少有一个异步方法是异步运行的,那么cpu绑定的代码将在某个线程池线程上运行。如果两者都同步完成,那么下面的代码将在调用线程上运行。那可能