Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.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# ContinueWith将丢失SynchronizationContext_C#_Asp.net_Asp.net Mvc_Async Await_C# 5.0 - Fatal编程技术网

C# ContinueWith将丢失SynchronizationContext

C# ContinueWith将丢失SynchronizationContext,c#,asp.net,asp.net-mvc,async-await,c#-5.0,C#,Asp.net,Asp.net Mvc,Async Await,C# 5.0,在下面的代码段中,SynchronizationContext丢失,因此,CurrentCulture和CurrentUICulture也会丢失日志()来自 公共异步任务索引() { 日志(“在GetAsync之前”); 等待新的HttpClient().GetAsync(“http://www.example.com/") .ContinueWith(请求=> { 日志(“连续性”); request.Result.EnsureSuccessStatusCode(); },TaskContin

在下面的代码段中,
SynchronizationContext
丢失,因此,
CurrentCulture
CurrentUICulture
也会丢失<代码>日志()来自

公共异步任务索引()
{
日志(“在GetAsync之前”);
等待新的HttpClient().GetAsync(“http://www.example.com/")
.ContinueWith(请求=>
{
日志(“连续性”);
request.Result.EnsureSuccessStatusCode();
},TaskContinuationOptions.AttachedToParent);
返回视图();
}
静态无效日志(字符串消息)
{
var ctx=System.Threading.SynchronizationContext.Current;
System.Diagnostics.Debug.Print(“{0};线程:{1},上下文:{2},区域性:{3},uiculture:{4}”,
消息
System.Threading.Thread.CurrentThread.ManagedThreadId,
ctx!=null?ctx.GetType()。名称:String.Empty,
System.Threading.Thread.CurrentThread.CurrentCulture.Name,
System.Threading.Thread.CurrentThread.CurrentUICulture.Name);
}
这是输出:

在GetAsync之前;线程:56,上下文:AspNetSynchronizationContext,区域性:nl,ui区域性:nl
继续;线程:46,上下文:,文化:nl BE,uiculture:en US

GetAsync
之前,区域性和UI区域性具有我在
Application\u BeginRequest
中设置的值。在
ContinueWith
中,缺少上下文,区域性设置为浏览器提供的内容,UI区域性设置为某些默认值


据我所知,所有带有
AspNetSynchronizationContext
的内容都应该自动发生。我的代码出了什么问题?

您是否尝试了
任务继续选项。同步执行?它应该在同一线程中运行延续任务


“指定应同步执行延续任务。指定此选项后,将在导致先行任务转换为最终状态的同一线程上运行继续。如果在创建延续时先行项已经完成,则延续将在创建延续的线程上运行。只能同步执行非常短的连续性。“

为了强制在请求上下文线程上调度连续性,您需要指定在调度连续性时应使用的
TaskScheduler

public async Task<ActionResult> Index()
{
    Log("before GetAsync");
    await new HttpClient().GetAsync("http://www.example.com/")
        .ContinueWith(request =>
        {
            Log("ContinueWith");
            request.Result.EnsureSuccessStatusCode();
        }, 
        TaskContinuationOptions.AttachedToParent,
        CancellationToken.None,
        TaskScheduler.FromCurrentSynchronizationContext());

    return View();
}

这没有帮助,我已经尝试了
TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.executes同步执行
TaskContinuationOptions.executes同步执行
。第一个代码段的重载不正确,但是
CancellationToken.None,TaskContinuationOptions.AttachedToParent,TaskScheduler.from同步上下文()
编译并传递上下文。是否为
取消令牌。无
正确?第二个代码段也不太正确。@Stijn发现得很好。我总是很清楚这个重载。它只是第二个代码段中的分号吗?在第二个代码段中,
请求
没有定义,我不确定您要键入什么e snippet.@Gusdor:每个方法都捕获自己的上下文,因此无论
GetAsync
是否使用
ConfigureAwait(false)
await
都会做正确的事情,即使它这样做了。
ConfigureAwait(true)
@Gusdor:很抱歉。我试图在
Each”级别解释它异步方法调用的一部分有自己的上下文
这篇文章的一部分。不过,这有点难以解释。您确定需要使用
ContinueWith
TaskContinuationOptions进行
continuation操作吗?附件为OPARENT
?检查以确保
TaskContinuationOptions.AttachedToParent
为您提供了预期的行为。@nosratio我相信是的。看见如果我的解决方案不正确,请随意发布一个更好的解决方案。@Noseratio避免
ContinueWith
是否更好?我开始觉得我在无缘无故地把自己挖进一个洞里。简言之,我正在执行一个Web API请求,反序列化响应并执行回调。是的,我认为您确实不需要在这里使用
ContinueWith
。为什么你不能只使用
async/await
?@Noseratio这个项目是我们第一次使用
async
,我想在我们的尝试中,我们发现
ContinueWith
(似乎)起了作用,我们最终保留了代码。我将尝试重新编写通话,谢谢您的输入。
public async Task<ActionResult> Index()
{
    Log("before GetAsync");
    await new HttpClient().GetAsync("http://www.example.com/")
        .ContinueWith(request =>
        {
            Log("ContinueWith");
            request.Result.EnsureSuccessStatusCode();
        }, 
        TaskContinuationOptions.AttachedToParent,
        CancellationToken.None,
        TaskScheduler.FromCurrentSynchronizationContext());

    return View();
}
public async Task<ActionResult> Index()
    {
        Log("before GetAsync");
        HttpResponseMessage request = await new HttpClient().GetAsync("http://www.example.com/");

        //everything below here is you 'continuation' on the request context
        Log("ContinueWith");
        request.EnsureSuccessStatusCode();

        return View();
    }