Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/33.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# 我应该在同步上下文中使用Task.Run来等待任务吗?_C#_Asp.net_Async Await - Fatal编程技术网

C# 我应该在同步上下文中使用Task.Run来等待任务吗?

C# 我应该在同步上下文中使用Task.Run来等待任务吗?,c#,asp.net,async-await,C#,Asp.net,Async Await,我有一个ASPX页面,无法转换为async,但它在同步上下文中使用了一些async方法。它调用它们的方式如下: public void MySyncMethod() { var myTask = Task.Run(() => _myField.DoSomethingAsync()); myTask.Wait(); //use myTask.Result } 就async/await和/或阻塞而言,这样做与以下操作有什么区别吗 public void MySyncM

我有一个ASPX页面,无法转换为
async
,但它在同步上下文中使用了一些
async
方法。它调用它们的方式如下:

public void MySyncMethod()
{
    var myTask = Task.Run(() => _myField.DoSomethingAsync());
    myTask.Wait();
    //use myTask.Result
}
async/await
和/或阻塞而言,这样做与以下操作有什么区别吗

public void MySyncMethod()
{
    var myTask = _myField.DoSomethingAsync(); //just get the Task direct, no Task.Run
    myTask.Wait();
    //use myTask.Result
}
我假设以前的开发人员添加了
任务。运行
是有原因的。但是我在访问
HttpContext
中的内容时遇到了问题,因为工作是在不同的线程上运行的

是否有理由使用
任务。在此处运行

那么,这样做和下面所说的有什么区别吗 异步/等待和/或阻塞

public void MySyncMethod()
{
    var myTask = _myField.DoSomethingAsync(); //just get the Task direct, no Task.Run
    myTask.Wait();
    //use myTask.Result
}
是的,第一段代码使用一个线程池线程,然后等待该线程返回,因此您使用的是两个线程,而不是一个线程。他们两个都挡住了

我假设以前的开发人员添加了任务。运行是有原因的

是的,在ASP.Net上下文中(直接)阻止
async
代码是一种错误。因此,第二块代码效率更高(在线程使用方面),但存在严重的死锁问题

这里的正确解决方案是使
公共无效MySyncMethod()
异步本身(
公共异步任务MySyncMethod()
)。这两种解决方案都有缺点,唯一真正的出路是使整个调用堆栈
异步
如果你能做到,就去做。

如果您不能从另一个
async
方法调用
async
方法,那么
Task.Run
就是一种方法。有关更多详细信息,请参阅

如果您想在线程中阅读
HttpContext
,尽管我绝对赞成:

  • 或者
选择这些答案并牢记在心

那么,这样做和下面所说的有什么区别吗 异步/等待和/或阻塞

public void MySyncMethod()
{
    var myTask = _myField.DoSomethingAsync(); //just get the Task direct, no Task.Run
    myTask.Wait();
    //use myTask.Result
}
是的,第一段代码使用一个线程池线程,然后等待该线程返回,因此您使用的是两个线程,而不是一个线程。他们两个都挡住了

我假设以前的开发人员添加了任务。运行是有原因的

是的,在ASP.Net上下文中(直接)阻止
async
代码是一种错误。因此,第二块代码效率更高(在线程使用方面),但存在严重的死锁问题

这里的正确解决方案是使
公共无效MySyncMethod()
异步本身(
公共异步任务MySyncMethod()
)。这两种解决方案都有缺点,唯一真正的出路是使整个调用堆栈
异步
如果你能做到,就去做。

如果您不能从另一个
async
方法调用
async
方法,那么
Task.Run
就是一种方法。有关更多详细信息,请参阅

如果您想在线程中阅读
HttpContext
,尽管我绝对赞成:

  • 或者
选择这些答案并牢记在心


基于
async
/
await
的异步代码的内部工作方式与通过
Task.Run
启动的任务有根本不同
async
/
await
任务是基于承诺的,并且取决于调用方在适当时配合将执行返回到异步方法。但是,由
Task.Run
启动的任务通常在线程池中的并行线程上启动,并且在适当的时候不依赖调用方的合作来继续执行

此星座导致的问题是,您不能将基于承诺的任务与其他任务一样对待,因为基于承诺的任务可能会等待调用者合作返回执行,而这可能永远不会发生,因为其他任务是独立执行的,并且可能会等待调用者。结果是僵局

解决方案是为现有基于任务的方法创建代理,该方法允许正确执行基于承诺的任务。在此代理上调用
Wait
是安全的。这就是为什么其他开发人员使用这个构造。他还可以简化调用,避免使用这样的匿名方法:

var myTask = Task.Run(_myField.DoSomethingAsync);

基于
async
/
await
的异步代码的内部工作方式与通过
Task.Run
启动的任务有根本不同
async
/
await
任务是基于承诺的,并且取决于调用方在适当时配合将执行返回到异步方法。但是,由
Task.Run
启动的任务通常在线程池中的并行线程上启动,并且在适当的时候不依赖调用方的合作来继续执行

此星座导致的问题是,您不能将基于承诺的任务与其他任务一样对待,因为基于承诺的任务可能会等待调用者合作返回执行,而这可能永远不会发生,因为其他任务是独立执行的,并且可能会等待调用者。结果是僵局

解决方案是为现有基于任务的方法创建代理,该方法允许正确执行基于承诺的任务。在此代理上调用
Wait
是安全的。这就是为什么其他开发人员使用这个构造。他还可以简化调用,避免使用这样的匿名方法:

var myTask = Task.Run(_myField.DoSomethingAsync);

如果任务也是异步的,则不需要将任务添加到task.Run中。Run用于异步运行同步代码。在可能的情况下,如果您不能使代码本身异步(并且您应该尽最大努力),如果系统同时提供同步和异步,则使用同步API。在这里,您不会从异步中获益,因为您会阻止请求线程。如果任务也是异步的,则不需要将任务添加到task.Run中。任务。运行