如果您知道您的库只会在单个同步上下文中使用,那么我认为没有理由不能使用静态成员(您的选项 A)捕获同步上下文。
为什么您认为需要使这种依赖关系“显式”?
选项 A 可能存在问题的地方是,您的库是否可以同时从多个同步上下文中使用。(例如在它们自己的线程和消息泵上运行的多个 UI 窗口)。不过这很不寻常——大多数情况下,您只有一个 UI 线程和一个同步上下文。
此外,如果应用程序希望在不强制序列化到 UI 线程(通过同步上下文)的情况下处理某些事件,则它不能这样做。
如果这些问题对您的图书馆来说不是问题,那么选项 A 应该是可行的。
编辑 - 回应评论:
Joel,我不确定这是否对您所描述的内容有所帮助,但是如果您有时想要使用显式同步上下文,您可能需要考虑的一件事是使用线程本地存储来存储参数而无需创建重写方法以获取参数。
例如,过去我自己需要允许我的 API 的调用者既使用当前调用线程的默认同步上下文,又显式设置不同的同步上下文。我可以采取的一种方法是提供允许传递同步上下文参数的 API 方法的重载。在我的情况下,这将非常难看,因为这意味着为相当少见的用例创建大量方法重载。
所以,我所做的是创建一个类来处理创建一个“范围”,在此期间当前同步上下文被覆盖(从而有效地将其传递给被调用的方法)。该类负责(按顺序)1)缓存当前同步上下文,2)将当前上下文设置为调用者指定的同步上下文,以及 3)在“范围”末尾重置同步上下文。
这是它的样子:
public class SyncContextScope : IDisposable
{
SynchronizationContext m_contextOnEntry;
/// <summary>
/// Constructor
/// </summary>
/// <param name="useContext"></param>
public SyncContextScope(SynchronizationContext useContext)
{
m_contextOnEntry = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(useContext);
}
#region IDisposable Members
void IDisposable.Dispose()
{
SynchronizationContext.SetSynchronizationContext(m_contextOnEntry);
}
#endregion
}
你像这样使用它:
using(new SyncContextScope(yourSyncContext))
{
yourApi.CallSomeMethod();
}
您的 API 方法(在上面的示例 CallSomeMethod 中)现在可以使用 SynchronizationContext.Current(它使用 TLS 来存储同步上下文)。所有这些都无需求助于提供 sychronizationcontext 参数。