我不确定何时应该使用ContentPresenter而不是ContentControl(反之亦然).目前,我ContentControl几乎一直在使用我DataTemplate的.何时会ContentPresenter是更好的选择?为什么?
使用Reactive Extensions,我想忽略来自我的Subscribe方法运行时发生的事件流的消息.也就是说,处理消息的时间有时比消息之间的时间长,所以我想删除没有时间处理的消息.
但是,当我的Subscribe方法完成时,如果有任何消息确实通过,我想处理最后一个消息.所以我总是处理最新消息.
所以,如果我有一些代码可以:
messages.OnNext(100);
messages.OnNext(1);
messages.OnNext(2);
Run Code Online (Sandbox Code Playgroud)
如果我们假设'100'需要很长时间来处理.然后我希望在'100'完成时处理'2'.应该忽略'1',因为它仍然被'2'取代,而'100'仍在处理中.
这是我想要使用后台任务的结果示例 Latest()
var messages = Observable.Interval(TimeSpan.FromMilliseconds(100));
Task.Factory.StartNew(() =>
{
foreach(var n in messages.Latest())
{
Thread.Sleep(TimeSpan.FromMilliseconds(250));
Console.WriteLine(n);
}
});
Run Code Online (Sandbox Code Playgroud)
但是,Latest()是一个阻塞调用,我宁愿不让一个线程等待下一个这样的值(消息之间有时会有很长的间隙).
我也可以使用BroadcastBlock来自TPL Dataflow的结果得到我想要的结果,如下所示:
var buffer = new BroadcastBlock<long>(n => n);
Observable.Interval(TimeSpan.FromMilliseconds(100)).Subscribe(n => buffer.Post(n));
buffer.AsObservable()
.Subscribe(n =>
{
Thread.Sleep(TimeSpan.FromMilliseconds(250));
Console.WriteLine(n);
});
Run Code Online (Sandbox Code Playgroud)
但感觉它应该可以直接在Rx中使用.这是最好的方法吗?
在C#.NET 3.5应用程序(WinForms和WPF的混合)中,我想让用户选择一个文件夹来导入一大堆数据.目前,它正在使用,System.Windows.Forms.FolderBrowserDialog但有点蹩脚.主要是因为您无法在其中键入路径(因此您需要映射网络驱动器,而不是键入UNC路径).
我想要更喜欢的东西System.Windows.Forms.OpenFileDialog,但是对于文件夹而不是文件.
我可以用什么呢?WinForms或WPF解决方案很好,但如果我能避免它,我宁愿不要将PInvoke引入Windows API.
在这个关于关于Subject<T>Enigmativity 的问题的答案中提到:
另外,你应该尽量避免使用主题.一般规则是,如果你正在使用一个主题,那么你做错了什么.
我经常使用主题作为IObservable属性的支持字段,这可能是在Rx之前的几天中的.NET事件.例如,而不是像
public class Thing
{
public event EventHandler SomethingHappened;
private void DoSomething()
{
Blah();
SomethingHappened(this, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
我可能会这样做
public class Thing
{
private readonly Subject<Unit> somethingHappened = new Subject<Unit>();
public IObservable<Unit> SomethingHappened
{
get { return somethingHappened; }
}
private void DoSomething()
{
Blah();
somethingHappened.OnNext(Unit.Default);
}
}
Run Code Online (Sandbox Code Playgroud)
那么,如果我想避免使用Subject什么是正确的方式来做这种事情?或者我应该坚持在我的界面中使用.NET事件,即使它们被Rx代码使用(很可能FromEventPattern)?
此外,更多详细信息,为什么使用Subject这样一个坏主意将是有帮助的.
更新:为了使这个问题更加具体,我正在讨论使用Subject<T>从非Rx代码(可能是你正在使用其他一些遗留代码)到Rx世界的方法.所以,像:
class MyVolumeCallback : LegacyApiForSomeHardware
{
private readonly Subject<int> volumeChanged …Run Code Online (Sandbox Code Playgroud) HttpServerUtility.UrlPathEncode和之间有什么区别HttpServerUtility.UrlEncode?什么时候我应该选择另一个?
我遇到了在.NET中序列化大量对象的问题.对象图非常大,使用了一些新的数据集,所以我得到:
System.Runtime.Serialization.SerializationException
"The internal array cannot expand to greater than Int32.MaxValue elements."
Run Code Online (Sandbox Code Playgroud)
还有其他人达到这个限制吗?你是怎么解决的?
如果可能的话我仍然可以使用内置的序列化机制会很好,但似乎只需要自己滚动(并保持与现有数据文件的向后兼容性)
对象都是POCO,并且正在使用它们进行序列化BinaryFormatter.被序列化的每个对象实现ISerializable选择性地序列化其成员(其中一些在加载期间重新计算).
对于MS来说,这看起来像是一个未解决的问题(详情请参见此处),但它已被解决为Wont Fix.细节是(来自链接):
对于具有超过~1320万个对象的对象图,二进制序列化失败.尝试这样做会导致ObjectIDGenerator.Rehash中出现异常,并引用一个引用Int32.MaxValue的误导性错误消息.
在检查SSCLI源代码中的ObjectIDGenerator.cs后,似乎可以通过在sizes数组中添加其他条目来处理更大的对象图.请参阅以下行:
Run Code Online (Sandbox Code Playgroud)// Table of prime numbers to use as hash table sizes. Each entry is the // smallest prime number larger than twice the previous entry. private static readonly int[] sizes = {5, 11, 29, 47, 97, 197, 397, 797, 1597, 3203, 6421, 12853, 25717, 51437, 102877, 205759, 411527, 823117, 1646237, 3292489, 6584983};但是,如果序列化适用于任何合理大小的对象图,那将是很好的.
当使用Josh Smith的RelayCommand时,我见过的大多数例子都使用延迟初始化,例如:
public class ViewModel
{
private ICommand myCommand;
public ICommand MyCommand
{
get
{
if (myCommand == null)
{
myCommand = new RelayCommand(p => DoSomething() );
}
return myCommand;
}
}
// ... stuff ...
}
Run Code Online (Sandbox Code Playgroud)
而不是在构造函数中创建RelayCommand,如下所示:
public class ViewModel
{
public ViewModel()
{
MyCommand = new RelayCommand(p => DoSomething());
}
public ICommand MyCommand
{
get;
private set;
}
// ... stuff ...
}
Run Code Online (Sandbox Code Playgroud)
在这里使用延迟初始化有什么好处?在设置绑定时必须调用get属性,所以我看不出在构造函数中使用此方法而不是设置的原因.
我在这里错过了什么吗?
我正在尝试使用MSBuild(在CruiseControl下)为我的.NET 4应用程序构建安装.安装版本应该创建一个boostrapper来安装先决条件(在这种情况下为.NET 4和Windows Installer 4.5),这是使用GenerateBootstrapper任务完成的.
MSBuild.exe project.msbuild.xml从安装了VS 2010的开发计算机上的命令行运行,运行正常.在仅具有最新Windows 7 SDK的构建计算机上运行失败,并显示以下错误:
(ProductDistributions target) -> bootstrapper.xml(236,5): error MSB3147:
Could not find required file 'setup.bin' in '<project path>\ProductDistributions\Engine'.
Run Code Online (Sandbox Code Playgroud)
在开发机器上,我有一个C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\Engine包含setup.bin文件的文件夹,但在构建机器上没有Bootstrapper文件夹C:\Program Files\Microsoft SDKs\Windows\v7.1(7.1 vs 7.0A显然是因为VS2010安装了7.0A,但独立SDK是7.1).
此外,在构建机器上没有4.0注册表项HKLM\Software\Microsoft\GenericBootstrapper\,但dev机器确实有一个包含值为的路径字符串c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bootstrapper\
看起来我需要在构建机器上安装一些东西,将Bootstrapper文件夹添加到"Microsoft SDKs\Windows\v7.1"(并设置注册表项),但我不确定那是什么.知道我需要得到什么吗?
或者还有什么我需要让我的安装版本工作?
更新:我现在通过手动将7.0A bootstrapper文件夹从开发机器复制到构建机器上,并手动将该路径添加到HKLM\Software\Microsoft\GenericBootstrapper\4.0注册表项来实现此功能.这似乎工作,但似乎这不是我应该做的解决问题.所以,如果有人对此有一个不太苛刻的解决方案,我会很感激.
我有一个带有Master-Details视图的应用程序.当您从"主"列表中选择一个项目时,它会使用一些图像(通过RenderTargetBitmap创建)填充"详细信息"区域.
每次我从列表中选择一个不同的主项目时,我的应用程序使用的GDI句柄数量(在Process Explorer中报告)会上升 - 并且最终会在使用的10,000个GDI句柄中翻倒(或有时会锁定).
我对如何解决这个问题感到茫然,所以对于我做错了什么建议(或者只是提供如何获取更多信息的建议)将不胜感激.
我在一个名为"DoesThisLeak"的新WPF应用程序(.NET 4.0)中将我的应用程序简化为以下内容:
在MainWindow.xaml.cs中
public partial class MainWindow : Window
{
public MainWindow()
{
ViewModel = new MasterViewModel();
InitializeComponent();
}
public MasterViewModel ViewModel { get; set; }
}
public class MasterViewModel : INotifyPropertyChanged
{
private MasterItem selectedMasterItem;
public IEnumerable<MasterItem> MasterItems
{
get
{
for (int i = 0; i < 100; i++)
{
yield return new MasterItem(i);
}
}
}
public MasterItem SelectedMasterItem
{
get { return selectedMasterItem; }
set
{
if (selectedMasterItem != value) …Run Code Online (Sandbox Code Playgroud) 我有一些使用Rx的代码,从多个线程调用,它执行:
subject.OnNext(value); // where subject is Subject<T>
Run Code Online (Sandbox Code Playgroud)
我希望在后台处理这些值,所以我的订阅是
subscription = subject.ObserveOn(Scheduler.TaskPool).Subscribe(value =>
{
// use value
});
Run Code Online (Sandbox Code Playgroud)
我并不关心哪些线程处理来自Observable的值,只要将工作放入TaskPool并且不阻止当前线程.但是,我在OnNext委托中使用'value'并不是线程安全的.目前,如果很多值正在通过Observable,我正在调用我的OnNext处理程序.
我可以为我的OnNext委托添加一个锁,但这不像Rx的做事方式.当我有多个线程调用时,确保我一次只调用一次OnNext处理程序的最佳方法是什么subject.OnNext(value);?