我在这个链接上找到了
ObservableCollection没有注意到它中的Item何时发生变化(即使使用INotifyPropertyChanged)
一些通知Observablecollection项目已更改的技术.这个链接中的TrulyObservableCollection似乎正是我正在寻找的.
public class TrulyObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
public TrulyObservableCollection()
: base()
{
CollectionChanged += new NotifyCollectionChangedEventHandler(TrulyObservableCollection_CollectionChanged);
}
void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Object item in e.NewItems)
{
(item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
if (e.OldItems != null)
{
foreach (Object item in e.OldItems)
{
(item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyCollectionChangedEventArgs a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
OnCollectionChanged(a); …Run Code Online (Sandbox Code Playgroud) c# collections wpf observablecollection inotifypropertychanged
何时实施IDisposable的最佳做法是什么?
如果在类中有一个托管对象,那么实现它是最好的经验法则,还是依赖于对象是在类中创建还是只是传入?我是否也应该为没有托管对象的类做到这一点?
通过WeakReference实现事件处理是一个好习惯,如果该事件是唯一持有引用的东西,并且我们需要对象进行垃圾回收?
作为一个论点:
人们说,如果你订阅某些东西,你有责任取消订阅,你应该这样做.
出于某种原因,我FileSystemWatcher没有发动任何事件.我想知道在我的目录中创建,删除或重命名新文件的任何时间._myFolderPath正确设置,我已经检查过了.
这是我目前的代码:
public void Setup() {
var fileSystemWatcher = new FileSystemWatcher(_myFolderPath);
fileSystemWatcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
fileSystemWatcher.Changed += FileSystemWatcherChanged;
fileSystemWatcher.Created += FileSystemWatcherChanged;
fileSystemWatcher.Deleted += FileSystemWatcherChanged;
fileSystemWatcher.Renamed += FileSystemWatcherChanged;
fileSystemWatcher.Filter = "*.*";
fileSystemWatcher.EnableRaisingEvents = true;
}
private void FileSystemWatcherChanged(object sender, FileSystemEventArgs e)
{
MessageBox.Show("Queue changed");
listBoxQueuedForms.Items.Clear();
foreach (var fileInfo in Directory.GetFiles(_myFolderPath, "*.*", SearchOption.TopDirectoryOnly))
{
listBoxQueuedForms.Items.Add(fileInfo));
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用FileSystemWatcher(在ASP.NET Web应用程序中)监视文件以进行更改.观察者在Singleton类的构造函数中设置,例如:
private SingletonConstructor()
{
var fileToWatch = "{absolute path to file}";
var fsw = new FileSystemWatcher(
Path.GetDirectoryName(fileToWatch),
Path.GetFileName(fileToWatch));
fsw.Changed += OnFileChanged;
fsw.EnableRaisingEvents = true;
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
// process file...
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切正常.但我的问题是:
使用局部变量(var fsw)设置观察者是否安全?或者我应该在私有字段中保留它的引用,以防止它被垃圾收集?
我阅读了解释如何使用Dispose模式的优秀答案,以及它为什么以这种方式工作.
该帖明确指出您希望在两种不同的场景中使用Dispose模式:
我的问题是:
由于C#使用垃圾收集.什么时候需要使用.Dispose释放内存?
我意识到有一些情况所以我会尝试列出我能想到的.
我偶然发现垃圾收集似乎在运行与单元测试相同的代码与在Main控制台应用程序的方法中编写的相同代码之间表现不同.我想知道这种差异背后的原因.
在这种情况下,我和同事对于在垃圾收集上注册事件处理程序的效果存在分歧.我认为演示比仅仅向他发送一个高评级SO答案的链接更好.因此我写了一个简单的演示作为单元测试.
我的单元测试显示事情正常,因为我说他们应该.但是,我的同事编写了一个控制台应用程序,显示了他的工作方式,这意味着GC没有像我期望的那样在方法中的本地对象上发生Main.通过将我的测试中的代码移动到MainConsole Application项目的方法中,我能够重现他所看到的行为.
我想知道的是,为什么GC在Main控制台应用程序的方法中运行时似乎没有按预期收集对象.通过提取方法以便GC.Collect在不同方法中发生对范围的调用和对象超出范围,恢复了预期的行为.
这些是我用来定义测试的对象.只有一个带有事件的对象和一个为事件处理程序提供合适方法的对象.两者都有终结器设置一个全局变量,以便您可以知道它们何时被收集.
private static string Log;
public const string EventedObjectDisposed = "EventedObject disposed";
public const string HandlingObjectDisposed = "HandlingObject disposed";
private class EventedObject
{
public event Action DoIt;
~EventedObject()
{
Log = EventedObjectDisposed;
}
protected virtual void OnDoIt()
{
Action handler = DoIt;
if (handler != null) handler();
}
}
private class HandlingObject
{
~HandlingObject()
{
Log = HandlingObjectDisposed;
}
public void Yeah()
{ …Run Code Online (Sandbox Code Playgroud) 我有以下代码(为了便于阅读而减少):
主类:
public StartProcess()
{
Thinker th = new Thinker();
th.DoneThinking += new Thinker.ProcessingFinished(ThinkerFinished);
th.StartThinking();
}
void ThinkerFinished()
{
Console.WriteLine("Thinker finished");
}
Run Code Online (Sandbox Code Playgroud)
思想家班级:
public class Thinker
{
private System.Timers.Timer t;
public delegate void ProcessingFinished();
public event ProcessingFinished DoneThinking;
BackgroundWorker backgroundThread;
public Thinker() { }
public StartThinking()
{
t = new System.Timers.Timer(5000); // 5 second timer
t.AutoReset = false;
t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
t.Start();
// start a background thread to do the thinking
backgroundThread = new BackgroundWorker();
backgroundThread.DoWork += new DoWorkEventHandler(BgThread_DoWork); …Run Code Online (Sandbox Code Playgroud) 例如,这样的事情有什么问题吗?
private void button1_Click(object sender, EventArgs e)
{
Packet packet = new Packet();
packet.DataNotSent += packet_DataNotSent;
packet.Send();
}
private void packet_DataNotSent(object sender, EventArgs e)
{
Console.WriteLine("Packet wasn't sent.");
}
class Packet
{
public event EventHandler DataNotSent;
public void Send()
{
if (DataNotSent != null)
{
DataNotSent(null, EventArgs.Empty);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果它只是一个简单的整数变量声明它会没问题,因为一旦它超出范围,后来被垃圾收集器收集,但事件有点......更长寿?我是否必须手动取消订阅或采取任何措施以确保其正常工作?
它只是感觉......很奇怪.不确定它是否正确.通常当我添加到事件处理程序时,它会持续整个应用程序,所以我不确定在不断添加和删除事件处理程序时会发生什么.
c# ×10
.net ×6
asp.net ×1
collections ×1
events ×1
idisposable ×1
memory-leaks ×1
vb.net ×1
wpf ×1