- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个使用 TaskCompletionSource 包装回调的方法,如下所示:
public Task<int> TestMethod(int argument)
{
var tcs = new TaskCompletionSource<int>();
var task = tcs.Task;
LegacyMethodWithCallback(argument, (returnValue) => tcs.TrySetResult(returnValue));
return task;
}
然后我等待那个方法:
async int CallingMethod()
{
var returnValue = await TestMethod(5);
Console.WriteLine(returnValue);
return returnValue;
}
编辑:LegacyMethodWithCallback 是一种使用网络与服务器通信的方法。回调在属于我们专有线程池的线程上运行(这是实现自定义 SynchronizationContext 的原因)。自定义 SynchronizationContext 基本上是空白的,除了它的 Post 方法将委托(delegate)排入线程池。以下是调用 Post 时应演示的 SC 实现:
internal class ServiceSynchronizationContext : SynchronizationContext
{
public override void Post(SendOrPostCallback d, object state)
{
Console.WriteLine("Post " + d + ": " + state + " for " + this.serviceLogic.ServiceLogicId);
// Enqueue the delegate into our thread pool
}
}
我已经实现了自己的同步上下文,但我惊讶地发现 CallingMethod 似乎在调用 TrySetResult 的同一个线程(因此调用回调的同一个线程)上立即恢复。我最初希望继续通过 SynchronizationContext 发布。
这种行为是否得到保证,或者是否存在调用 SynchronizationContext(或任何其他线程)的情况?如果此行为不是完全确定的,我能否以某种方式控制它?
我彻底检查了 CallingMethod 恢复时的调用堆栈,似乎甚至没有考虑 SynchronizationContext(但仍有一些代码无法轻易查看),因此看起来确实可以保证这种行为。我说得对吗?
最佳答案
Is this behavior guaranteed or are there any cases in which the SynchronizationContext (or any other thread) is invoked?
SynchronizationContext(如果存在)始终由等待代码使用(除非 ConfigureAwait(false)
另有指定)。这意味着如果您无法控制等待代码,则不能假定等待代码将在您的线程上运行。
有几个原因让你的延续不被内联到同一个线程上。一个是是否使用 TaskCreationOptions.RunContinuationsAsynchronously
。其他像当前的 SynchronizationContext
和 TaskScheduler
都在 IsValidLocationForInlining
中:
internal static bool IsValidLocationForInlining
{
get
{
// If there's a SynchronizationContext, we'll be conservative and say
// this is a bad location to inline.
var ctx = SynchronizationContext.CurrentNoFlow;
if (ctx != null && ctx.GetType() != typeof(SynchronizationContext)) return false;
// Similarly, if there's a non-default TaskScheduler, we'll be conservative
// and say this is a bad location to inline.
var sched = TaskScheduler.InternalCurrent;
return sched == null || sched == TaskScheduler.Default;
}
}
关于c# - TaskCompletionSource 是否保证等待代码将在调用 TCS.TrySetResult 的线程上恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37695275/
我试图了解 TCS 启用的 SGX 线程与 SDK 提供的不受信任线程之间的区别. 如果我理解正确的话,TCS 允许多个逻辑处理器进入同一个飞地。每个逻辑处理器都有自己的 TCS,因此也有自己的入口点
async 关键字do 导致 CIL更改(即使方法内部没有 await),但主要是为了允许 await 出现。 但我没想到会发生以下情况: static void Main(string[] args
我想在 Ubuntu 14.04 64 位上使用 jTSS,我有版本 1.2 的硬件 TPM。我按照 4.3 http://trustedjava.sourceforge.net/index.php?
这是我一直在试验的一段代码: #include #include "GL/gl3w.h" #include "GLFW/glfw3.h" #include #include #include
我有一个使用 TaskCompletionSource 包装回调的方法,如下所示: public Task TestMethod(int argument) { var tcs = new T
我正在尝试解决 TCS MockVita 2019 Round 2 中提出的问题: 问题描述 高斯学校的数学老师 Felix Kline 博士介绍了以下游戏来教他的学生解决问题。他将一系列“跳石”(纸
我是一名优秀的程序员,十分优秀!