标签: synchronizationcontext

.Net 核心 & SynchronizationContext & Thread.SetData

据我所知,AspNetCore没有 SynchronizationContext.

“重新进入”请求上下文涉及许多内务任务,例如设置 HttpContext.Current 和当前线程的身份和文化。

所以我创建了一个简单的 .Net Core Api 项目,并执行以下操作:

    [HttpGet]
    [Route("checkVar")]
    public async Task<IActionResult> checkVar()
    {
        Thread.SetData(Thread.GetNamedDataSlot("Random"),4);
        await Task.Delay(1000);
        var res = Thread.GetData(Thread.GetNamedDataSlot("Random"));
    }
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,res它的价值为4. 我很惊讶,因为我相信这SetData是同步上下文的一部分。(在asp.net core中不应该存在)

更多,当我使用时ConfigureAwait(false),我进入nullres

所以现在我很困惑。因为ConfigureAwait 在asp.net core中不应该有影响

题:

如果 asp.net core 没有 SynchronizationContext,那么为什么在4之后可用await?为什么会ConfigureAwait在非 SynchronizationContext 环境中改变结果?

c# synchronizationcontext async-await asp.net-core

9
推荐指数
1
解决办法
3747
查看次数

Security,Thread.CurrentPrincipal和ConfigureAwait(false)

在使用ConfigureAwait(false)的引用库中使用Thread.CurrentPrincipal的声明会造成任何问题,或者ExecutionContext的逻辑调用上下文的流动会在那里照顾我吗?(到目前为止,我的阅读和测试表明它会).

示例WebAPI控制器操作:

[CustomAuthorizeThatSetsCurrentUsersClaimsToThreadCurrentContextAndHttpContextCurrentUser]
public async Task<Order> Get(int orderId)
{
    return await _orderBusinessLogicLibrary.LoadAsync(orderId); // defaults to .ConfigureAwait(true)
}
Run Code Online (Sandbox Code Playgroud)

来自外部引用库的示例加载函数:

[ClaimsPrincipalPermission(
    SecurityAction.Demand,
    Operation="Read",
    Resource="Orders")]
[ClaimsPrincipalPermission(
    SecurityAction.Demand,
    Operation="Read",
    Resource="OrderItems")]
public async Task<Order> Load(int orderId)
{
    var order = await _repository.LoadOrderAsync(orderId).ConfigureAwait(false);

    // here's the key line.. assuming this lower-level function is also imposing
    // security constraints in the same way this method does, would
    // Thread.CurrentPrincipal still be correct inside the function below?
    order.Items = await _repository.LoadOrderItemsAsync(orderId).ConfigureAwait(false);
    return order;
}
Run Code Online (Sandbox Code Playgroud)

此外,答案不能是"那么不要使用ConfigureAwait(false)!".这可能会导致其他问题,例如死锁(请勿在异步代码上阻止).

claims-based-identity synchronizationcontext async-await current-principal executioncontext

8
推荐指数
1
解决办法
2326
查看次数

Task.Start,Task.RunSynchronously和同步上下文

我手动构建一个任务:

var task = new Task(() => 
    Debug.WriteLine("Task"));
Run Code Online (Sandbox Code Playgroud)

然后手动启动它:

task.Start(TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

我希望它能通过预定SynchronizationContext.Post.

但如果以这种方式启动它:

task.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

是通过SynchronizationContext.Send调用任务的lambda 来执行还是直接执行?

.net c# task synchronizationcontext task-parallel-library

8
推荐指数
1
解决办法
4910
查看次数

在Windows服务中使用ConfigureAwait(false)?

据我所知,Windows服务应用程序中没有同步上下文.

  • 是否await fooTask.ConfigureAwait(false)给我的Windows服务中的任何好处?
  • 这有什么陷阱吗?

c# windows-services synchronizationcontext task-parallel-library async-await

8
推荐指数
1
解决办法
1047
查看次数

如何将SynchronizationContext与WCF一起使用

我正在阅读SynchronizationContext并尝试确保OperationContext即使在await通话之后我试图将所有线程都流入所有线程也不会弄乱任何东西.

我有这SynchronizationContext门课:

public class OperationContextSynchronizationContext : SynchronizationContext
{

    // Track the context to make sure that it flows through to the next thread.

    private readonly OperationContext _context;

    public OperationContextSynchronizationContext(OperationContext context)
    {
        _context = context;
    }

    public override void Post(SendOrPostCallback d, object state)
    {
        OperationContext.Current = _context;
        d(state);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后围绕每个方法调用(使用a Ninject IInterceptor)调用它:

var original = SynchronizationContext.Current;
try
{
    // Make sure that the OperationContext flows across to the other threads,
    // …
Run Code Online (Sandbox Code Playgroud)

wcf synchronizationcontext

8
推荐指数
1
解决办法
2751
查看次数

WPF +任务+ WCF =没有SynchronizationContext?

我有一个WPF应用程序,它使用System.Threading.Tasks在后台调用WCF服务.我正在使用Task.ContinueWith将服务调用的结果返回给WPF UI线程.我的问题是,虽然继续运行确实在UI线程上运行,但是它确实是SynchronizationContext.Current为null.我可以运行相同的代码,在初始Task中注释掉WCF调用,并且继续在UI线程上,并按预期使用DispatcherSynchronizationContext.

WCF代理使用ChannelFactory生成,并使用wsHttpBinding.没有回调合约.相关代码如下所示:

    private TaskScheduler _uiScheduler;

    public MainWindow()
    {
        InitializeComponent();
        _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var serviceTask = new Task<Int32>(ServiceCallWrapper, 
            CancellationToken.None, 
            TaskCreationOptions.None);

        var continueTask = serviceTask.ContinueWith(result => ServiceContinuation(result.Result),
                                                    CancellationToken.None,
                                                    TaskContinuationOptions.OnlyOnRanToCompletion, 
                                                    _uiScheduler);

        serviceTask.Start();
    }

    private Int32 ServiceCallWrapper()
    {
        Int32 result = 0;

        var service = {elided - initializes service using ChannelFactory };
        result = service.TheServiceMethod();
        service.Close();

        return result;
    }

    private void ServiceContinuation(Int32 result)
    { elided }
Run Code Online (Sandbox Code Playgroud)

如果我按原样运行此代码,则在正确的线程上调用ServiceContinuation(使用ManagedThreadID验证),但SynchronizationContext.Current为null.如果我注释掉进行服务调用的单行(result = service.TheServiceMethod();),则使用DispatcherSynchronizationContext正确调用ServiceContinuation.

一个注意事项 - SynchronizationContext不会永久丢失 - 如果我再次单击该按钮,则按钮单击处理程序确实具有正确的SynchronizationContext.

我已经捕获了两个案例的堆栈跟踪; …

wpf wcf task synchronizationcontext

7
推荐指数
1
解决办法
2428
查看次数

由TaskScheduler和SynchronizationContext混淆同步异步,无法控制同步上下文?

问题

我有一个带有简单Web服务的ASP.NET 4.0 WebForms页面WebMethod.此方法用作异步/ TPL代码的同步包装器.我面临的问题是,内部Task有时会有一个null SynchronizationContext(我的偏好),但有时会有一个同步上下文System.Web.LegacyAspNetSynchronizationContext.在我提供的示例中,这并不会导致问题,但在我的实际开发场景中可能会导致死锁.

对服务的第一次调用似乎总是使用空同步上下文运行,接下来的几个也可能.但是一些快速激活的请求会开始弹出ASP.NET同步上下文.

代码

[WebMethod]
public static string MyWebMethod(string name)
{
    var rnd = new Random();
    int eventId = rnd.Next();
    TaskHolder holder = new TaskHolder(eventId);

    System.Diagnostics.Debug.WriteLine("Event Id: {0}. Web method thread Id: {1}",
        eventId,
        Thread.CurrentThread.ManagedThreadId);

    var taskResult = Task.Factory.StartNew(
        function: () => holder.SampleTask().Result,
        creationOptions: TaskCreationOptions.None,
        cancellationToken: System.Threading.CancellationToken.None,
        scheduler: TaskScheduler.Default)
        .Result;

    return "Hello " + name + ", result is " + taskResult;
}
Run Code Online (Sandbox Code Playgroud)

存在的定义TaskHolder:

public class TaskHolder …
Run Code Online (Sandbox Code Playgroud)

asp.net synchronizationcontext task-parallel-library webmethod async-await

7
推荐指数
1
解决办法
1911
查看次数

如何在MonoTouch中使用async/await忽略未观察到的异常?

在以前的MonoTouch版本中,我曾经这样做忽略了未观察到的异常:

TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) {
    Console.WriteLine (e);
    e.SetObserved ();
};
Run Code Online (Sandbox Code Playgroud)

这是否是一个好的做法是有争议的,但我想知道与Xamarin.iOS 6.4中正式支持的async/awaitkeywords 一起实现相同的效果.

这是我用于测试的代码:

async void OnClick (object sender, EventArgs e)
{
    await Task.Run (() => { throw new Exception (); });
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,调试器暂停AsyncVoidMethodBuilder:

在此输入图像描述

我读到.NET 4.5据说改变了行为,因此未观察到的异常不会使应用程序崩溃 - 但是如果将异常发布到UIKit同步上下文中我无法处理它们,这无济于事.

有没有办法忽略awaitMonoTouch中未观察到的异常?

c# xamarin.ios synchronizationcontext async-await c#-5.0

7
推荐指数
1
解决办法
1701
查看次数

使用async/await时,使用自定义SynchronizationContext序列化执行

我的团队正在使用C#5.0中的async/await开发一个多线程应用程序.在实现线程同步的过程中,经过几次迭代,我们想出了一个(可能是新颖的?)新的SynchronizationContext实现,它有一个内部锁:

  1. 在致电Post时:
    • 如果可以进行锁定,则立即执行委托
    • 如果无法获取锁定,则委托将排队
  2. 致电发送时:
    • 如果可以执行锁定,则执行委托
    • 如果无法进行锁定,则线程被阻止

在所有情况下,在执行委托之前,上下文将自身设置为当前上下文,并在委托返回时恢复原始上下文.

这是一个不寻常的模式,因为我们显然不是第一个写这样的应用程序的人,我想知道:

  1. 这种模式真的很安全吗?
  2. 有没有更好的方法来实现线程同步?

这是SerializingSynchronizationContext的源代码和GitHub上的一个演示.

以下是它的使用方法:

  • 每个需要保护的类都会像互斥锁一样创建自己的上下文实例.
  • 上下文是可以接受的,因此可以使用以下语句.

    await myContext;

    这只会导致方法的其余部分在上下文的保护下运行.

  • 该类的所有方法和属性都使用此模式来保护数据.在等待之间,一次只能有一个线程在上下文中运行,因此状态将保持一致.当达到await时,允许下一个计划的线程在上下文中运行.
  • 如果需要,自定义SynchronizationContext可以与AsyncLock结合使用,即使在等待表达式的情况下也能保持原子性.
  • 类的同步方法也可以使用自定义上下文进行保护.

.net c# synchronizationcontext async-await

7
推荐指数
1
解决办法
2496
查看次数

信号量等待与异步方法中的WaitAsync相同

我试图找出在这种情况下使用的SemaphoreSlim使用Wait和WaitAsync之间的区别:

private SemaphoreSlim semaphore = new SemaphoreSlim(1);
public async Task<string> Get()
{
   // What's the difference between using Wait and WaitAsync here?
   this.semaphore.Wait(); // await this.semaphore.WaitAsync()

   string result;
   try {
     result = this.GetStringAsync();
   }
   finally {
     this.semaphore.Release();
   }

   return result;
}
Run Code Online (Sandbox Code Playgroud)

c# concurrency semaphore synchronizationcontext

7
推荐指数
2
解决办法
6946
查看次数