标签: reactiveui

ReactiveUI ObservableAsPropertyHelper/Reactive Extensions内存泄漏?

我注意到在使用ReactiveUI的.NET 3.5应用程序中,我有一个显着的内存泄漏,似乎源自ObservableAsPropertyHelper.我创建了一个测试项目来证明它在这里.

似乎由简单的ObservableAsPropertyHelper计算属性触发的每个更改通知都会泄漏内存.泄漏似乎源于Reactive Extensions,而不是直接在ReactiveUI中,但我对OAPH的使用非常简单,我想知道是否有人遇到过这个或者可能有一个建议的修复.

内存泄漏的严重程度在.NET 3.5(RxUI 2.4,Rx 1.1)和.NET 4.0(RxUI 4.2,Rx 2.0.3)之间变化.它与.NET 3.5中每次更新属性更接近线性.但是,.NET 4.0中仍然存在漏洞.

我已经在这里使用测试应用程序上传了我的.NET 3.5和.NET 4.0测试会话的测试项目和一些探查器图像.

你可以在图像中看到对象图是不同的,所以我们可能完全在谈论两个不同的泄漏.在4.0会话(40_RetentionGraph.png)中,您可以看到分配最多的对象是Ints(我的OAPH属性的类型)和ConcurrentQueue.那里似乎有某种循环引用问题.您还可以在40_IntsAllocatedGCRootGrows.png中看到实例的GC根距离的增长.

在3.5版本(我最关心的)中,您可以看到(35_Summary.png)分配最多的对象是Action和ScheduledObserver.对象图比40版更复杂,完全不同.

我已经回顾了这个讨论,但还没有找到一个直接的答案:我的方案是,对OAPH进行非常简单的更新.任何有关这种泄漏的可能解决方案的见解都表示赞

.net memory-leaks system.reactive reactiveui

6
推荐指数
1
解决办法
1092
查看次数

以反应方式在窗口关闭时显示确认

我有一个observable,我用它来显示一个确认对话框,大致是签名:

IObservable<DialogResult> ShowDialog(string title, string message);
Run Code Online (Sandbox Code Playgroud)

这向用户显示了对话框,带有是/否按钮组合.

在我的主窗口中,我正在访问结束事件:

this.Events().Closing.[Do something here]
Run Code Online (Sandbox Code Playgroud)

我希望能够:

  1. 触发关闭observable时显示确认对话框
  2. CancelEventArgs.Cancel如果用户单击"否"按钮,则将该属性设置为true.

我试过直接订阅:

this.Events().Closing.Subscribe(e =>
{
    var res = Dialogs.ShowDialog("Close?", "Really Close?").Wait();
    e.Cancel = res == DialogResult.Ok;
});
Run Code Online (Sandbox Code Playgroud)

但是因为这个Wait()电话而挂起,我也尝试过异步变种:

this.Events().Closing.Subscribe(async e =>
{
    var res = await Dialogs.ShowDialog("Close?", "Really Close?");
    e.Cancel = res == DialogResult.Ok;
});
Run Code Online (Sandbox Code Playgroud)

哪个不好,因为它马上就会回来.

我真正想要做的是:

this.Events().Closing.ThenDo(_ => Dialogs.ShowDialog("Close?", "Really Close?"))
    .Subscribe((cancelEventArgs, dialogResult) =>
    {
        cancelEventArgs.Cancel == dialogResult == DialogResult.Ok;
    });
Run Code Online (Sandbox Code Playgroud)

但这不存在,我知道这里的关键在于我如何组合这两个可观察量,但我不知道如何这样做,而且文档对实际例子有点了解.

c# wpf mvvm reactiveui

6
推荐指数
1
解决办法
1040
查看次数

如何将ReactiveUI与分层数据源一起使用(树形视图)

我想出了一种使用ReactiveUI在树视图内动态绑定用户控件的方法。

但是... 到HierachicalDataSource的顶级绑定是在XAML中,而不是在后面的代码,我需要直接设置ItemsSource而不使用this.OneWayBind。

因此,我的问题是:我是否错过了ReactiveUI框架中的某些东西,该东西会让我与this.OneWayBind绑定,并将HierachicalDataTemplete移入代码或自定义用户控件中?

特别是-OneWayBind是否有另一个支持层次结构数据模板的重载,或者是一种抑制使用时调用的数据模板生成的方法?

更新 我已经在我的测试项目中添加了选定的项目以及对Expand和Selected的编程支持,但是我不得不向XAML添加样式。我也想用一个简单的RxUI Bind替换它。更新了示例。

以下是关键细节:

主视图中的树控件

<TreeView Name="FamilyTree" >
                <TreeView.Resources>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
                        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
                  </Style>
                    <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding Children}">
                        <reactiveUi:ViewModelViewHost ViewModel="{Binding ViewModel}"/>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
Run Code Online (Sandbox Code Playgroud)

后面的主视图代码

      public partial class MainWindow : Window, IViewFor<MainVM>
        {
            public MainWindow()
            {
                InitializeComponent();
                //build viewmodel
                ViewModel = new MainVM();
                //Register views
                Locator.CurrentMutable.Register(() => new PersonView(), typeof(IViewFor<Person>));
                Locator.CurrentMutable.Register(() => new PetView(), typeof(IViewFor<Pet>));
                //NB. ! Do not use 'this.OneWayBind ... ' …
Run Code Online (Sandbox Code Playgroud)

c# wpf treeview reactiveui

6
推荐指数
1
解决办法
878
查看次数

在ViewModelViewHost控件中托管的Views和ViewModel中使用时,调用两次WhenActivated

我的应用程序使用实现IViewFor<T>界面的视图.视图已在依赖项解析程序中注册AppBootstrapper.应用程序ViewModelViewHost通过为控件的ViewModel属性分配相应的视图模型来使用控件显示视图.所有视图模型都实现了ISupportsActivation接口.

我注意到它WhenActivated被叫了两次.首先,当视图和视图模型被激活时调用它.然后在停用时,处理所有一次性用品并WhenActivated立即再次调用,然后处理一次性用品.

我在视图和视图模型中使用以下代码进行测试:

this.WhenActivated(disposables =>
{
    Debug.WriteLine("ViewModel activated.");

    Disposable
        .Create(() =>
        {
            Debug.WriteLine("ViewModel deactivated.");
        })
        .AddTo(disposables);
});
Run Code Online (Sandbox Code Playgroud)

结果输出如下:

// App displays the view:

ViewModel activated.
View activated.

// App hides the view:

ViewModel deactivated.
View deactivated.
ViewModel activated.
View activated.
ViewModel deactivated.
View deactivated.
Run Code Online (Sandbox Code Playgroud)

通过将ViewModelViewHost控件的ViewModel属性设置为null来隐藏视图.

难道我做错了什么?

编辑:这是完整的源代码:https://gist.github.com/dmakaroff/e7d84e06e0a48d7f5298eb6b7d6187d0

按第一个Show然后按Hide按钮将产生以下输出:

SubViewModel activated.
SubView activated.
SubViewModel deactivated.
SubView deactivated.
SubViewModel activated.
SubView activated.
SubViewModel deactivated. …
Run Code Online (Sandbox Code Playgroud)

.net c# wpf reactiveui

6
推荐指数
1
解决办法
853
查看次数

ReactiveCommand.CreateFromTask vs ReactiveCommand.CreateFromObservable

我已经看到一些关于使用Observables而不是使用async/await的任务的讨论.我目前几乎只使用CreateFromTask.我一直试图理解使用CreateFromObservable而不是CreateFromTask的原因.

如果是这样,那么将CreateFromTask转换为CreateFromObservable的最佳方法是什么.

reactiveui

6
推荐指数
1
解决办法
1083
查看次数

引用ReactiveUI 7.4时iOS启动错误

我有一个带有.Net Standard 1.4核心库的Xamarin Forms项目,它包含所有代码.我在核心和iOS项目中都引用了ReactiveUI 7.4.但是当我在iOS模拟器上编译并运行时,我在应用程序启动时收到以下错误:

2017-08-24 13:39:39.040 TestProject.iOS[25074:307385] Could not register the assembly 'ReactiveUI': System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.12.0.20/src/mono/mcs/class/corlib/System.Reflection/Assembly.cs:410 
  at Registrar.DynamicRegistrar.CollectTypes (System.Reflection.Assembly assembly) [0x00000] in /Users/builder/data/lanes/4991/80b8487d/source/xamarin-macios/src/ObjCRuntime/DynamicRegistrar.cs:237 
  at Registrar.Registrar.RegisterAssembly (System.Reflection.Assembly assembly) [0x00056] in /Users/builder/data/lanes/4991/80b8487d/source/xamarin-macios/src/ObjCRuntime/Registrar.cs:1978 


Loaded assembly: /Library/Frameworks/Xamarin.Interactive.framework/Versions/Current/Agents/iOS/Xamarin.Interactive.iOS.dll [External]
Loaded assembly: /Library/Frameworks/Xamarin.Interactive.framework/Versions/Current/Agents/iOS/Xamarin.Interactive.dll [External]
Unhandled Exception:

System.BadImageFormatException: <Timeout exceeded getting exception details>
Run Code Online (Sandbox Code Playgroud)

Unhandled Exception:
System.BadImageFormatException: Could not resolve field token 0x040000fd
File name: 'ReactiveUI'
  at TestProject.iOS.AppDelegate..ctor () …
Run Code Online (Sandbox Code Playgroud)

xamarin.ios reactiveui xamarin xamarin.forms

6
推荐指数
1
解决办法
432
查看次数

无法在"设计"视图中编辑ReactiveUserControl

我将UserControl更改为ReactiveUserControl,现在我无法查看设计视图.有什么办法可以让设计师使用ReactiveUserControl吗?

wpf xaml reactiveui

6
推荐指数
1
解决办法
772
查看次数

ReactiveUI ObservableAsPropertyHelper 与普通支持变量

我在 ReactiveUI 的学习曲线上苦苦挣扎,所以这个问题可能很幼稚。请帮助我理解以下之间的区别:

ObservableAsPropertyHelper<string> _input
public string Input {get {return _input.Value;}}
Run Code Online (Sandbox Code Playgroud)

和一个普通的支持变量 RaiseAndSetIfChanged:

private string _input;
public string Input {
    get {return _input;}
    set {RaiseAndSetIfChanged(ref _input, value);}
}
Run Code Online (Sandbox Code Playgroud)

它们是给同一只猫剥皮的两种方法,还是两种选择有不同的用例/意图?

c# data-binding user-interface properties reactiveui

6
推荐指数
1
解决办法
508
查看次数

如何分离 IObservable 和 IObserver

更新:查看底部的示例

我需要在课间发消息。发布者将无限循环,调用一些方法来获取数据,然后将该调用的结果传递给OnNext. 可以有很多订阅者,但应该只有一个 IObservable 和一个长期运行的任务。这是一个实现。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Diagnostics;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        private static string GetSomeData() => "Hi";

        [TestMethod]
        public async Task RunMessagingAsync()
        {
            var subject = new Subject<string>();

            //Create a class and inject the subject as IObserver
            new Publisher(subject);

            //Create a class and inject the subject as IObservable
            new Subscriber(subject, 1.ToString());
            new Subscriber(subject, 2.ToString());
            new Subscriber(subject, 3.ToString());

            //Run the loop for 3 seconds
            await …
Run Code Online (Sandbox Code Playgroud)

c# publish-subscribe reactive-programming system.reactive reactiveui

6
推荐指数
1
解决办法
327
查看次数

如何将 WhenActivated 与 avalonia 中的属性一起使用

我正在尝试将 ReactiveUI 与 Avalonia 一起使用。由于 Avalonia 0.10 预览版中的初始化顺序,以下代码失败:

class ViewModel : IActivatableViewModel
{
    public ViewModel(){
        this.WhenActivated(disposables => {
            _myProperty = observable.ToProperty(this, nameof(MyProperty)).DisposeWith(disposables).
        });
    }

    private ObservableAsPropertyHelper<object> _myProperty = null!;
    public object MyProperty => _myProperty.Value;
}
Run Code Online (Sandbox Code Playgroud)

因为WhenActivated在视图绑定到 viewModel 之后调用(因此 _myProperty 为 null)。

我认为没有简单的解决方法需要大量的修改、手动提高属性等等。

所以问题是:

如何在 Avalonia 中使用 OAPH 和 WhenActivated?

c# reactiveui avaloniaui avalonia

6
推荐指数
1
解决办法
2312
查看次数