在 WPF 中使用 Unity 解析时 SynchronizationContext.Current 为 null

发布于 2025-01-07 14:52:24 字数 1173 浏览 4 评论 0原文

我有一个 WPF 代码,看起来像这样。

public class AlphaProductesVM : BaseModel
{
    private  ObservableCollection<Alphabetical_list_of_product> _NwCustomers;
    private int i = 0;

    public AlphaProductesVM ()
    {
        _NwCustomers = new ObservableCollection<Alphabetical_list_of_product>();
        var repository = new NorthwindRepository();
           repository
               .GetAllProducts()
               .ObserveOn(SynchronizationContext.Current)
               .Subscribe(AddElement);
    }
    public void AddElements(IEnumerable<Alphabetical_list_of_product> elements)
    {
        foreach (var alphabeticalListOfProduct in elements)
        {
            AddElement(alphabeticalListOfProduct);
        }
    }


    public ObservableCollection<Alphabetical_list_of_product> NwCustomers
    {
        get { return _NwCustomers; }
        set { _NwCustomers = value; }
    }}

我使用 Unity 来解决上述 AlphaProductesVM。当使用 PRISM 和 UnityBootstrapper 发现模块时,这是即时的。在运行时,.ObserveOn(SynchronizationContext.Current) 会引发异常,并且 SynchronizationContext.Current 中有一个 null 值。

I have a WPF Code which looks something like this.

public class AlphaProductesVM : BaseModel
{
    private  ObservableCollection<Alphabetical_list_of_product> _NwCustomers;
    private int i = 0;

    public AlphaProductesVM ()
    {
        _NwCustomers = new ObservableCollection<Alphabetical_list_of_product>();
        var repository = new NorthwindRepository();
           repository
               .GetAllProducts()
               .ObserveOn(SynchronizationContext.Current)
               .Subscribe(AddElement);
    }
    public void AddElements(IEnumerable<Alphabetical_list_of_product> elements)
    {
        foreach (var alphabeticalListOfProduct in elements)
        {
            AddElement(alphabeticalListOfProduct);
        }
    }


    public ObservableCollection<Alphabetical_list_of_product> NwCustomers
    {
        get { return _NwCustomers; }
        set { _NwCustomers = value; }
    }}

I use Unity to Resolve the above AlphaProductesVM. This is instant when the Module is discovered using PRISM and the UnityBootstrapper. At runtime .ObserveOn(SynchronizationContext.Current) throws an exception and SynchronizationContext.Current has a null value in it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蒲公英的约定 2025-01-14 14:52:24

SynchronizationContext.Current 属性将仅在主线程上调用时返回值

如果您需要在线程中使用 SynchronizationContext 对象,主线程,您可以传递 SynchronizationContext 实例与主线程关联到需要它作为依赖项的类。

如果您选择此解决方案,您可以注册从SynchronizationContext.Current 属性在主线程上作为容器中的单例。这样,从那时起对 SynchronizationContext 的所有请求都将自动得到满足通过带有单例的容器:

// Must run in the main thread
container.RegisterInstance(SynchronizationContext.Current);

The SynchronizationContext.Current property will only return a value when invoked on the main thread.

If you need to use a SynchronizationContext object in threads other than the main thread, you could pass the SynchronizationContext instance associated to the main thread to the classes that need it as a dependency.

If you choose this solution, you could register the SynchronizationContext object obtained from the SynchronizationContext.Current property on the main thread as a singleton in your container. That way all requests for a SynchronizationContext from that point on will automatically be satisfied by the container with the singleton:

// Must run in the main thread
container.RegisterInstance(SynchronizationContext.Current);
木槿暧夏七纪年 2025-01-14 14:52:24

尽管有 WPF 的 SynchronizationContext 实现,但不建议使用。 WPF 具有用于构建响应式应用程序Dispatcher

此外,仅当您位于 UI 线程上时,SynchronizationContext.Current 才有值。如果您的逻辑在后台线程中运行,Current 将始终为 null。

Although there is an implementation of SynchronizationContextfor WPF it is not recommended for use. WPF has the Dispatcher to build responsive applications.

In addition SynchronizationContext.Current only has a value if you are on the UI thread. If your logic runs in a background thread Current will always be null.

像极了他 2025-01-14 14:52:24

我不确定这是否会是一个受欢迎的建议,但您可以懒惰地创建并订阅您的收藏。然后,从 UI 线程第一次访问 NwCustomers 将正确启动一切。

public AlphaProductesVM (){}

public ObservableCollection<Alphabetical_list_of_product> NwCustomers
{
    get { 
          if(_NwCustomers == null)
          {
              _NwCustomers = new ObservableCollection<Alphabetical_list_of_product>();
              var repository = new NorthwindRepository();
                  repository
                  .GetAllProducts()
                  .ObserveOn(SynchronizationContext.Current)
                  .Subscribe(AddElement);
          }
          return _NwCustomers; 
    }
}

或者,如果您将 UI 线程的调度程序注入到视图模型中,您可以在构造函数中订阅它。

              var repository = new NorthwindRepository();
                  repository
                  .GetAllProducts()
                  .ObserveOn(theUIdispatcher)
                  .Subscribe(AddElement);

I'm not sure if this will be a popular suggestion, but you could lazily create and subscribe to your collection. Then the first access to NwCustomers from the UI thread will kick everything off correctly.

public AlphaProductesVM (){}

public ObservableCollection<Alphabetical_list_of_product> NwCustomers
{
    get { 
          if(_NwCustomers == null)
          {
              _NwCustomers = new ObservableCollection<Alphabetical_list_of_product>();
              var repository = new NorthwindRepository();
                  repository
                  .GetAllProducts()
                  .ObserveOn(SynchronizationContext.Current)
                  .Subscribe(AddElement);
          }
          return _NwCustomers; 
    }
}

or, if you inject the UI thread's dispatcher into your view model you can subscribe on that in the constructor.

              var repository = new NorthwindRepository();
                  repository
                  .GetAllProducts()
                  .ObserveOn(theUIdispatcher)
                  .Subscribe(AddElement);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文