gpt4 book ai didi

c# - 从 SynchronizationContext 派生

转载 作者:行者123 更新时间:2023-11-30 16:32:35 25 4
gpt4 key购买 nike

简而言之,我已经实现了一个派生自 SynchronizationContext 的类,以便 GUI 应用程序可以轻松地使用在 GUI 线程以外的线程上引发的事件。我非常感谢对我的实现的评论。具体来说,有什么你会反对或可能导致我没有预见到的问题的吗?我的初始测试已经成功。

长版:我目前正在开发分布式系统 (WCF) 的业务层,该系统使用回调将事件从服务器传播到客户端。我的设计目标之一是提供可绑定(bind)的业务对象(即 INotifyPropertyChanged/IEditableObject 等),以便在客户端轻松使用这些对象。作为其中的一部分,我提供了一个回调接口(interface)的实现,它在事件传入时处理事件,更新业务对象,进而引发属性更改事件。因此,我需要在 GUI 线程上引发这些事件(以避免跨线程操作异常)。因此,我尝试提供自定义 SynchronizationContext,实现回调接口(interface)的类使用它来将事件传播到 GUI 线程。此外,我希望这个实现独立于客户端环境——例如WinForms GUI 应用程序或 ConsoleApp 或其他东西。换句话说,我不想假设静态 SynchronizationContext.Current 可用。因此,我使用 ExecutionContext 作为后备策略。

public class ImplicitSynchronisationContext : SynchronizationContext

{

private readonly ExecutionContext m_ExecContext;
private readonly SynchronizationContext m_SyncContext;


public ImplicitSynchronisationContext()
{
// Default to the current sync context if available.
if (SynchronizationContext.Current != null)
{
m_SyncContext = SynchronizationContext.Current;
}
else
{
m_ExecContext = ExecutionContext.Capture();
}
}


public override void Post(SendOrPostCallback d, object state)
{
if (m_SyncContext != null)
{
m_SyncContext.Post(d, state);
}
else
{
ExecutionContext.Run(
m_ExecContext.CreateCopy(),
(object args) =>
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.Invoker), args);
},
new object[] { d, state });
}
}
public override void Send(SendOrPostCallback d, object state)
{
if (m_SyncContext != null)
{
m_SyncContext.Send(d, state);
}
else
{
ExecutionContext.Run(
m_ExecContext.CreateCopy(),
new ContextCallback(this.Invoker),
new object[] { d, state });
}
}


private void Invoker(object args)
{
Debug.Assert(args != null);
Debug.Assert(args is object[]);

object[] parts = (object[])args;

Debug.Assert(parts.Length == 2);
Debug.Assert(parts[0] is SendOrPostCallback);

SendOrPostCallback d = (parts[0] as SendOrPostCallback);

d(parts[1]);
}

最佳答案

不幸的是你写了一些已经存在的东西。 SynchronizationContext 类完全按照您的要求进行操作。向您的主类添加一个属性,类似于此:

    public static SynchronizationContext SynchronizationContext {
get {
if (SynchronizationContext.Current == null) {
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
return SynchronizationContext.Current;
}
}

或者使用 AsyncOperationManager.SynchronizationContext,它做的事情完全一样。当然更好。

关于c# - 从 SynchronizationContext 派生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3944498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com