Does Anyone Know How To Run This Extended Version Of FileSystemWatcher? - c#

I found this code and it looks like a fixed version of the C# version of FileSystemWatcher from Microsoft. However the problem is that I have no idea how to use or run it. Could someone with some expertise please shed some light for me? How do I use this code?
The original source and explanation is here I believe. I've tried to contact the originator but I cannot get a response.
http://fascinatedwithsoftware.com/blog/post/2012/12/30/How-to-Use-FileSystemWatcher-Instead-of-Polling.aspx
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Threading;
namespace Fws.Collections
{
/// <summary>
/// Detects the arrival of files in a directory and makes them available to a client class
/// as an IEnumerable of fully pathed file names. Unlike the .NET FileSystemWatcher, this
/// class yields files that exist when the object is constructed. Also, it is not an IDisposable.
/// </summary>
/// <remarks>
/// <para>
/// If a file arrives during the execution of this class's constructor, it may be reported more than
/// once. Also, some programs write their files in such a way that the underlying FileSystemWatcher
/// will fire a Create event more than once. In those cases, this class will yield the
/// file multiple times.
/// </para><para>
/// Client code must account for these possibilities. It is envisioned that wrapping classes may
/// refine the yielded files by waiting for them to quiesce, filtering out duplicates, etc.
/// </para>
/// <para>
/// This class is thread-safe: more than one thread may enumerate the files presented by a
/// single instance of this class, and each thread will get all the files.
/// </para>
/// </remarks>
public sealed class CreatedFileCollection : IEnumerable<string>
{
#region Fields
readonly string _directory;
readonly string _filePattern;
readonly CancellationToken _cancellationToken;
#endregion
#region Nested Class to Collect Results
/// <summary>
/// A queue of files found within one GetEnumerator call.
/// </summary>
private sealed class CreatedFileQueue : IDisposable
{
readonly ConcurrentQueue<string> _queue = new ConcurrentQueue<string>();
readonly SemaphoreSlim _fileEnqueued = new SemaphoreSlim(0);
/// <summary>
/// Attempt to get a file from the queue.
/// </summary>
/// <param name="fileName">The name of the file, if one is immediately available.</param>
/// <returns>True if got a file; false if not.</returns>
public bool TryDequeue(out string fileName, CancellationToken cancellationToken)
{
fileName = null;
// Avoid the OperationCanceledException if we can.
if (cancellationToken.IsCancellationRequested)
return false;
try
{
_fileEnqueued.Wait(cancellationToken);
return _queue.TryDequeue(out fileName);
}
catch (OperationCanceledException)
{
return false;
}
}
/// <summary>
/// Handles the Created event of the enclosing class's FileSystemWatcher.
/// </summary>
/// <param name="sender">This object.</param>
/// <param name="e">Args for the new file.</param>
public void FileCreated(object sender, FileSystemEventArgs e)
{
_queue.Enqueue(e.FullPath);
_fileEnqueued.Release();
}
public void Dispose()
{
_fileEnqueued.Dispose();
}
}
#endregion
#region Constructor
/// <summary>
/// Constructor.
/// </summary>
/// <param name="cancellationToken">This class will terminate the enumeration of
/// files when and only when the token enters the canceled state.</param>
/// <param name="directory">The directory to watch.</param>
/// <param name="filePattern">A pattern to match in the file name. Example: "*.txt".
/// Null means all files.</param>
/// <remarks>Duplicates may be returned on the queue. See remarks for the class.</remarks>
public CreatedFileCollection(CancellationToken cancellationToken, string directory, string filePattern=null)
{
Contract.Requires(directory != null);
Contract.Requires(cancellationToken != null);
if (!Directory.Exists(directory))
throw new ArgumentException(String.Format("Directory '{0}' does not exist.", directory));
_directory = directory;
_filePattern = filePattern ?? "*";
_cancellationToken = cancellationToken;
}
#endregion
#region Methods
/// <summary>
/// Get an enumerator that will yield files until the CanellationToken is canceled.
/// </summary>
/// <returns>Fully pathed file names.</returns>
/// <remarks>
/// It is possible for a file name to be returned from more than once.
/// </remarks>
public IEnumerator<string> GetEnumerator()
{
if (!_cancellationToken.IsCancellationRequested)
{
using (var watcher = new FileSystemWatcher(_directory, _filePattern))
{
using (var queue = new CreatedFileQueue())
{
// Restrict the NotifyFilter to all that's necessary for Create events.
// This minimizes the likelihood that FileSystemWatcher's buffer will be overwhelmed.
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += queue.FileCreated;
watcher.EnableRaisingEvents = true;
// Note that if a file arrives during the following loop, it will be placed on the queue
// twice: once when the Create event is raised, and once by the loop itself.
foreach (var file in Directory.GetFiles(_directory, _filePattern, SearchOption.TopDirectoryOnly))
{
queue.FileCreated(this, new FileSystemEventArgs(WatcherChangeTypes.Created, _directory, Path.GetFileName(file)));
}
if (!_cancellationToken.IsCancellationRequested)
{
string fileName;
while (queue.TryDequeue(out fileName, _cancellationToken))
yield return fileName;
}
}
}
}
}
/// <summary>
/// Required method for IEnumerable.
/// </summary>
/// <returns>The generic enumerator, but as a non-generic version.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}

Here is an example I knocked up which seems to work.
public static void Main()
{
var watcher = new CreatedFileCollection(CancellationToken.None, "c:\\test");
var enumerator = watcher.GetEnumerator();
Task.Run(() =>
{
//This will block until either a new file is created or the
//passed CancellationToken is cancelled.
while (enumerator.MoveNext())
{
Console.WriteLine("New File - " + enumerator.Current);
}
});
Console.ReadLine();
}
This will print a line for all files that are created while the program is running.

Related

Where is the python in this script being called/pulled from?

I found a project in Unity 5 where python can be run in Unity, and i want to add libraries to it. The trouble is, i can't seem to find where the python libraries from this script. To me, it looks like they're being generated out of thin air. Can i have a pointer as to where this might be coming from? I tried adding it to python path, and its not seeming to work.
using System;
using System.IO;
using System.Linq;
using UnityEngine;
using System.Text;
using System.Collections;
using IronPython.Hosting;
using IronPython.Modules;
using System.Collections.Generic;
using Microsoft.Scripting.Hosting;
/// <summary>
/// Interpreter for IronPython.
/// </summary>
public class Interpreter
{
/// <summary>
/// The scope.
/// </summary>
private ScriptScope Scope;
/// <summary>
/// The engine.
/// </summary>
private ScriptEngine Engine;
/// <summary>
/// The source.
/// </summary>
private ScriptSource Source;
/// <summary>
/// The compiled.
/// </summary>
private CompiledCode Compiled;
/// <summary>
/// The operation.
/// </summary>
private ObjectOperations Operation;
/// <summary>
/// The python class.
/// </summary>
private object PythonClass;
/// <summary>
/// Initializes a new instance of the <see cref="Interpreter"/> class.
/// </summary>
public Interpreter()
{
Engine = Python.CreateEngine();
Scope = Engine.CreateScope();
SetLibrary();
}
/// <summary>
/// Initializes a new instance of the <see cref="Interpreter"/> class.
/// </summary>
/// <param name="source">Source.</param>
public Interpreter(string src) : this()
{
Compile(src);
}
/// <summary>
/// Compile the specified src.
/// </summary>
/// <param name="src">Source.</param>
public string Compile(string src, Microsoft.Scripting.SourceCodeKind CodeKind =
Microsoft.Scripting.SourceCodeKind.SingleStatement)
{
if(src == string.Empty)
return string.Empty;
LoadRuntime();
Source = CodeKind == Microsoft.Scripting.SourceCodeKind.SingleStatement ?
Engine.CreateScriptSourceFromString(src, CodeKind) :
Engine.CreateScriptSourceFromFile(src);
ErrorHandle errors = new ErrorHandle();
MemoryStream stream = new MemoryStream();
//Set IO Ouput of execution
Engine.Runtime.IO.SetOutput(stream, new StreamWriter(stream));
Compiled = Source.Compile(errors);
Operation = Engine.CreateOperations();
try {
Compiled.Execute(Scope);
return FormatOutput(ReadFromStream(stream));
} catch(Exception ex) {
return Engine.GetService<ExceptionOperations>().FormatException(ex);
}
}
/// <summary>
/// Formats the output of execution
/// </summary>
/// <returns>The output.</returns>
/// <param name="output">Output.</param>
private string FormatOutput(string output)
{
return string.IsNullOrEmpty(output) ? string.Empty
: string.Join("\n", output.Remove(output.Length-1)
.Split('\n')
.Reverse().ToArray());
}
/// <summary>
/// Reads MemoryStream.
/// </summary>
/// <returns>The from stream.</returns>
/// <param name="ms">Ms.</param>
private string ReadFromStream(MemoryStream ms) {
int length = (int)ms.Length;
Byte[] bytes = new Byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(bytes, 0, length);
return Encoding.GetEncoding("utf-8").GetString(bytes, 0, length);
}
/// <summary>
/// Set sys paths
/// </summary>
private void SetLibrary()
{
if(PythonBase.SysPath.Count > 0) {
ICollection<string> SysPath = Engine.GetSearchPaths();
foreach(string path in PythonBase.SysPath)
SysPath.Add(path);
Engine.SetSearchPaths(SysPath);
}
}
/// <summary>
/// Load runtime Assemblies of Unity3D
/// </summary>
private void LoadRuntime()
{
Engine.Runtime.LoadAssembly(typeof(GameObject).Assembly);
}
public void AddRuntime<T>()
{
Engine.Runtime.LoadAssembly(typeof(T).Assembly);
}
public void AddRuntime(Type type)
{
Engine.Runtime.LoadAssembly(type.Assembly);
}
/// <summary>
/// Gets the variable or class
/// </summary>
/// <returns>The variable.</returns>
/// <param name="name">Name.</param>
public object GetVariable(string name)
{
return Operation.Invoke(Scope.GetVariable(name));
}
/// <summary>
/// Calls the method.
/// </summary>
/// <param name="name">Name.</param>
public void InvokeMethod(object nameClass, string Method, params object[] parameters)
{
object output = new object();
if(Operation.TryGetMember(nameClass, Method, out output)) {
object Func = Operation.GetMember(nameClass, Method);
Operation.Invoke(Func, parameters);
}
}
}

I can't deal with the fileSystemWatcher

Today my problem is in that i can't deal with the fileSystemWatcher (even with debug).
So... i want to use the function GetHashFromFile(string path, HashAlgorithm algorithm ) while the fileSystemWatcher is watching the choosen directory. Once it gets an change in this directory (File has been created, re-named, change..) i want to use the e.fullPath as 1st argument in GetHashFromFile, but it throws me an exception about that this file can't be found. Could someone tell me on wich place in the code should i use the GetHashFromFile() ?
Thanks !
Here is some sample code which I created for a different SO question which correctly uses FileSystemWatcher to process files which should meet your needs
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Reactive.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Security.Permissions;
namespace ConsoleApplication9
{
internal class Program
{
private static void Main(string[] args)
{
const string directorytowatch = #"d:\junk\watch\"; // the directory to watch for new files
// this initiates a filesystemmonitor to watch for new files being created
Task.Factory.StartNew(() => FileSystemMonitor.Instance.WatchDirectory(directorytowatch));
// initiate the processing of any new files
FilesWorker.Instance.ReadQueue();
Console.ReadLine();
}
}
/// <summary>
/// Monitors the filesystem in "real-time" to check for new files
/// </summary>
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
internal class FileSystemMonitor : SingletonBase<FileSystemMonitor>
{
private FileSystemMonitor()
{
}
internal void WatchDirectory(string dir)
{
var watcher = new FileSystemWatcher(dir)
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.LastAccess,
Filter = "*.*"
};
// watch all files
watcher.Created += WatcherOnCreated;
watcher.EnableRaisingEvents = true;
}
private static void WatcherOnCreated(object sender, FileSystemEventArgs fileSystemEventArgs)
{
Console.WriteLine(fileSystemEventArgs.FullPath + "" + fileSystemEventArgs.ChangeType); // for test purposes
var fileInfo = new FileInfo(fileSystemEventArgs.FullPath);
FilesWorker.Instance.AddToQueue(fileInfo);
}
}
/// <summary>
/// handles the queue of files to be processed and the syncronisation of tasks related to the queue
/// </summary>
internal class FilesWorker : SingletonBase<FilesWorker>
{
private FilesWorker()
{
}
/// <summary>
/// The queue of files which still need to be processed
/// </summary>
private readonly ConcurrentQueue<FileInfo> _filesQueue = new ConcurrentQueue<FileInfo>();
/// <summary>
/// create a semaphore to limit the number of threads which can process a file at any given time
// In this case only allow 2 to be processed at any given time
/// </summary>
private static readonly SemaphoreSlim Semaphore = new SemaphoreSlim(2, 2);
/// <summary>
/// add new file to the queue
/// </summary>
/// <param name="fileInfo"></param>
internal void AddToQueue(FileInfo fileInfo)
{
_filesQueue.Enqueue(fileInfo);
}
/// <summary>
/// executes a method on a given timeframe
/// </summary>
/// <param name="method">method to execute</param>
/// <param name="timer">time between execution runs (seconds)</param>
internal void ExecuteMethod(Action method, double timer)
{
IObservable<long> observable = Observable.Interval(TimeSpan.FromSeconds(timer));
// Token for cancelation
var source = new CancellationTokenSource();
observable.Subscribe(x =>
{
var task = new Task(method);
task.Start();
}, source.Token);
}
/// <summary>
/// Get any new files and send for processing
/// </summary>
internal void ReadQueue()
{
// check the queue every two seconds
ExecuteMethod(ProcessQueue, 2d);
}
/// <summary>
/// takes files from the queue and starts processing
/// </summary>
internal void ProcessQueue()
{
try
{
Semaphore.Wait();
FileInfo fileInfo;
while (_filesQueue.TryDequeue(out fileInfo))
{
var fileProcessor = new FileProcessor();
fileProcessor.ProcessFile(fileInfo);
}
}
finally
{
Semaphore.Release();
}
}
}
internal class FileProcessor
{
internal void ProcessFile(FileInfo fileInfo)
{
// do some long running tasks with the file
}
}
/// <summary>
/// Implements singleton pattern on all classes which derive from it
/// </summary>
/// <typeparam name="T">Derived class</typeparam>
public abstract class SingletonBase<T> where T : class
{
public static T Instance
{
get { return SingletonFactory.Instance; }
}
/// <summary>
/// The singleton class factory to create the singleton instance.
/// </summary>
private class SingletonFactory
{
static SingletonFactory()
{
}
private SingletonFactory()
{
}
internal static readonly T Instance = GetInstance();
private static T GetInstance()
{
var theType = typeof(T);
T inst;
try
{
inst = (T)theType
.InvokeMember(theType.Name,
BindingFlags.CreateInstance | BindingFlags.Instance
| BindingFlags.NonPublic,
null, null, null,
CultureInfo.InvariantCulture);
}
catch (MissingMethodException ex)
{
var exception = new TypeLoadException(string.Format(
CultureInfo.CurrentCulture,
"The type '{0}' must have a private constructor to " +
"be used in the Singleton pattern.", theType.FullName)
, ex);
//LogManager.LogException(LogManager.EventIdInternal, exception, "error in instantiating the singleton");
throw exception;
}
return inst;
}
}
}
}

Syncing between multiple instances of the same program

I have quite a complicated programming problem on my hands, so bear with me for a few minutes.
I decided i want to create a media player in WPF (C#) and i've run into a bit of a pickle.
I want my application to be single instance, so that when the user double clicks server files, the program would only run once and queue all files for playing.
I tried several ways of doing it, including Microsoft's single instance implementation, and nothing seemed to work, until i decided to create my own, as in i though of something and implemented it (this probably was on the internet somewhere as well, but it didn't show up)
Basically, i use a named mutex to prevent more than one instance from being opened, and to force the other instances to write their arguments to a file, and after that, the instance which created the mutex would read the file.
Needless to say, this is very, very ineffective as far as performance goes, but anyway, here is my implementation of the Main() function.
Note that this Main() is also written from scratch, as i didn't really like the one automatically generated by the VS2010.
static void Main(string[] args)
{
string[] arguments = new string[0];
handler g = new handler();
bool createdNew = false;
Mutex lolpaca = new Mutex(true, "lolpacamaximumtrolololololol", out createdNew);
if (createdNew)
{
if (args != null)
{
var MainWindow = new MainWindow();
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
else
{
Array.Resize(ref arguments, 1);
arguments[0] = args[0];
string line;
//nu mai arunca exceptii nenorocitule
while ((line = g.ReadArgs()) != null)
{
int old_size = arguments.Length;
Array.Resize(ref arguments, arguments.Length + 1);
arguments[old_size] = line;
}
var MainWindow = new MainWindow(arguments, arguments.Length);
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
if (File.Exists(path))
{
File.Delete(path);
}
}
else
{
Thread writer = new Thread(new ParameterizedThreadStart(g.WriteArg));
writer.Start(args);
writer.Join();
try
{
g.WriteArg(args);
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
}
I'm also using this class to attempt to sync between the threads
public class handler
{
static string path = #"D:\playlist.txt";
static FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
string line;
string arg;
bool readerFlag = false;
public string ReadArgs()
{
try
{
lock (fs) // Enter synchronization block
{
if (!readerFlag)
{ // Wait until writer finishes
try
{
// Waits for the Monitor.Pulse in WriteArg
Monitor.Wait(fs);
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
TextReader tr = new StreamReader(fs);
while ((line = tr.ReadLine()) != null)
{
arg = line;
}
tr.Close();
tr.Dispose();
}
/* fs.Close();
fs.Dispose();*/
readerFlag = false;
Monitor.Pulse(fs);
return arg;
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
return null;
}
}
public void WriteArg(object args)
{
lock (fs)
{
try
{
if (readerFlag)
{
try
{
Monitor.Wait(fs); // Wait for the Monitor.Pulse in ReadArgs
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
arg = Convert.ToString(args);
// FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
TextWriter tw = new StreamWriter(fs);
tw.WriteLine(args);
tw.Close();
tw.Dispose();
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
/* fs.Close();
fs.Dispose();*/
readerFlag = true;
Monitor.Pulse(fs);
}
}
Now, basically, for each double clicked file, one instance of the Main() function is created by Windows.
The first instance has control over the mutex and proceeds to doing whatever it wants to do.
The other instances must write their argument to the file.
Now, the problem:
Apparently, the threads (all of them) do no sync properly, and sometimes i get IO exceptions.
I have no clue where exactly these exceptions are thrown, because the try-catch blocks seem to do exactly nothing. In fact, I believe this is a little deeper than try-catch would work on.
So, how do i sync all the threads that spawn when the user double clicks a lot of files? This implementation works ok with up to 3 double clicked files, and sometimes (note, sometimes it works, other times it doesn't) with more than 3 files (tested with up to 9).
Nothing i found so far on the internet accounts for several instances of the same application running independently.
It would be great if you could give me an example:)
Thank you.
The best way to talk between two instances of the same application is use IPC. Bellow see example of class that can be used to help with single instance:
/// <summary>
/// Enforces single instance for an application.
/// </summary>
public class SingleInstance : IDisposable
{
#region Fields
/// <summary>
/// The synchronization context.
/// </summary>
private readonly SynchronizationContext synchronizationContext;
/// <summary>
/// The disposed.
/// </summary>
private bool disposed;
/// <summary>
/// The identifier.
/// </summary>
private Guid identifier = Guid.Empty;
/// <summary>
/// The mutex.
/// </summary>
private Mutex mutex;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="SingleInstance"/> class.
/// </summary>
/// <param name="identifier">
/// An identifier unique to this application.
/// </param>
/// <param name="args">
/// The command line arguments.
/// </param>
public SingleInstance(Guid identifier, IEnumerable<string> args)
{
this.identifier = identifier;
bool ownsMutex;
this.mutex = new Mutex(true, identifier.ToString(), out ownsMutex);
this.synchronizationContext = SynchronizationContext.Current;
this.FirstInstance = ownsMutex;
if (this.FirstInstance)
{
this.ListenAsync();
}
else
{
this.NotifyFirstInstance(args);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="SingleInstance"/> class.
/// </summary>
/// <param name="identifier">
/// An identifier unique to this application.
/// </param>
public SingleInstance(Guid identifier)
: this(identifier, null)
{
}
#endregion
#region Public Events
/// <summary>
/// Event raised when arguments are received from successive instances.
/// </summary>
public event EventHandler<OtherInstanceCreatedEventArgs> OtherInstanceCreated;
#endregion
#region Public Properties
/// <summary>
/// Gets a value indicating whether this is the first instance of this application.
/// </summary>
public bool FirstInstance { get; private set; }
#endregion
#region Implemented Interfaces
#region IDisposable
/// <summary>
/// The dispose.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#endregion
#region Methods
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">
/// True if managed resources should be disposed; otherwise, false.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (this.disposed)
{
return;
}
if (disposing)
{
if (this.mutex != null && this.FirstInstance)
{
this.mutex.WaitOne();
this.mutex.ReleaseMutex();
this.mutex = null;
}
}
this.disposed = true;
}
/// <summary>
/// Fires the OtherInstanceCreated event.
/// </summary>
/// <param name="arguments">
/// The arguments to pass with the <see cref="OtherInstanceCreatedEventArgs"/> class.
/// </param>
protected virtual void OnOtherInstanceCreated(OtherInstanceCreatedEventArgs arguments)
{
EventHandler<OtherInstanceCreatedEventArgs> handler = this.OtherInstanceCreated;
if (handler != null)
{
handler(this, arguments);
}
}
/// <summary>
/// Listens for arguments on a named pipe.
/// </summary>
private void Listen()
{
try
{
using (var server = new NamedPipeServerStream(this.identifier.ToString()))
{
using (var reader = new StreamReader(server))
{
server.WaitForConnection();
var arguments = new List<string>();
while (server.IsConnected)
{
arguments.Add(reader.ReadLine());
}
this.synchronizationContext.Post(o => this.OnOtherInstanceCreated(new OtherInstanceCreatedEventArgs(arguments)), null);
}
}
// start listening again.
this.Listen();
}
catch (IOException)
{
// Pipe was broken, listen again.
this.Listen();
}
}
/// <summary>
/// Listens for arguments being passed from successive instances of the applicaiton.
/// </summary>
private void ListenAsync()
{
Task.Factory.StartNew(this.Listen, TaskCreationOptions.LongRunning);
}
/// <summary>
/// Passes the given arguments to the first running instance of the application.
/// </summary>
/// <param name="arguments">
/// The arguments to pass.
/// </param>
private void NotifyFirstInstance(IEnumerable<string> arguments)
{
try
{
using (var client = new NamedPipeClientStream(this.identifier.ToString()))
{
using (var writer = new StreamWriter(client))
{
client.Connect(200);
if (arguments != null)
{
foreach (string argument in arguments)
{
writer.WriteLine(argument);
}
}
}
}
}
catch (TimeoutException)
{
// Couldn't connect to server
}
catch (IOException)
{
// Pipe was broken
}
}
#endregion
}
/// <summary>
/// Holds a list of arguments given to an application at startup.
/// </summary>
public class OtherInstanceCreatedEventArgs : EventArgs
{
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="OtherInstanceCreatedEventArgs"/> class.
/// </summary>
/// <param name="args">
/// The command line arguments.
/// </param>
public OtherInstanceCreatedEventArgs(IEnumerable<string> args)
{
this.Args = args;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the startup arguments.
/// </summary>
public IEnumerable<string> Args { get; private set; }
#endregion
}
Then in your main class you can create instance of of class that will stay until aplication is running. You can check if other instance is created by FirstInstance property, And get notified of other instance created by OtherInstanceCreated event.

Does this implementation of the Entity Framework leaks memory?

I just can't make out if the entity context is disposed in the usage flow when used in a using statement in a web application or a console application.
Thanks!
using System;
using System.Web;
namespace Foo.Model
{
public partial class FooEntities : ObjectContext
{
private const string CurrentContextKey = "FooEntities.Current";
[ThreadStatic]
private static FooEntities _currentOnThreadStatic;
private FooEntities _previousContext;
/// <summary>
/// Gets the current <see cref="FooEntities"/> instance, if an instance can be shared in the current context.
/// </summary>
/// <remarks>
/// The current context is stored in the HTTP context, if it is available (otherwise it is stored in a thread-static instance).
/// Multiple contexts can be stacked.
/// </remarks>
public static FooEntities Current
{
get
{
if (HttpContext.Current != null)
{
return HttpContext.Current.Items[CurrentContextKey] as FooEntities;
}
else
{
return _currentOnThreadStatic;
}
}
private set
{
if (HttpContext.Current != null)
{
HttpContext.Current.Items[CurrentContextKey] = value;
}
else
{
_currentOnThreadStatic = value;
}
}
}
/// <summary>
/// Returns a repository instance bound to this object context.
/// </summary>
/// <typeparam name="TRepository">The type of repository to instantiate.</typeparam>
/// <returns>The repository instance.</returns>
public TRepository GetRepository<TRepository>()
where TRepository: BaseRepository
{
return (TRepository) Activator.CreateInstance(typeof(TRepository), this);
}
/// <summary>
/// Ensures that an ambient context is available through <see cref="Current"/>, throwing an exception otherwise.
/// </summary>
/// <exception type="InvalidOperationException)">
/// Thrown if <see cref="Current"/> is null.
/// </exception>
public static void EnsureContext()
{
if (Current == null)
{
throw new InvalidOperationException("An ambient FooEntities context is expected.");
}
}
/// <summary>
/// Releases the context instance.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
Current = _previousContext;
base.Dispose(disposing);
}
/// <summary>
/// Is called by all constructors.
/// </summary>
partial void OnContextCreated()
{
_previousContext = Current;
Current = this;
}
}
}
It is an odd design. As #Joel C points out in his comment you should regard the object context as a shortlived object that you create when you need it and release right afterwards.
But I see no reason that this would leak memory. You are only dealing with managed resources and you are using the same key all the time to the HttpContext so you won't create new objects all over.

About File permissions in C#

While creating a file synchronization program in C# I tried to make a method copy in LocalFileItem class that uses System.IO.File.Copy(destination.Path, Path, true) method where Path is a string.
After executing this code with destination. Path = "C:\\Test2" and this.Path = "C:\\Test\\F1.txt" I get an exception saying that I do not have the required file permissions to do this operation on C:\Test, but C:\Test is owned by myself (the current user).
Does anybody knows what is going on, or how to get around this?
Here is the original code complete.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Diones.Util.IO
{
/// <summary>
/// An object representation of a file or directory.
/// </summary>
public abstract class FileItem : IComparable
{
protected String path;
public String Path
{
set { this.path = value; }
get { return this.path; }
}
protected bool isDirectory;
public bool IsDirectory
{
set { this.isDirectory = value; }
get { return this.isDirectory; }
}
/// <summary>
/// Delete this fileItem.
/// </summary>
public abstract void delete();
/// <summary>
/// Delete this directory and all of its elements.
/// </summary>
protected abstract void deleteRecursive();
/// <summary>
/// Copy this fileItem to the destination directory.
/// </summary>
public abstract void copy(FileItem fileD);
/// <summary>
/// Copy this directory and all of its elements
/// to the destination directory.
/// </summary>
protected abstract void copyRecursive(FileItem fileD);
/// <summary>
/// Creates a FileItem from a string path.
/// </summary>
/// <param name="path"></param>
public FileItem(String path)
{
Path = path;
if (path.EndsWith("\\") || path.EndsWith("/")) IsDirectory = true;
else IsDirectory = false;
}
/// <summary>
/// Creates a FileItem from a FileSource directory.
/// </summary>
/// <param name="directory"></param>
public FileItem(FileSource directory)
{
Path = directory.Path;
}
public override String ToString()
{
return Path;
}
public abstract int CompareTo(object b);
}
/// <summary>
/// A file or directory on the hard disk
/// </summary>
public class LocalFileItem : FileItem
{
public override void delete()
{
if (!IsDirectory) File.Delete(this.Path);
else deleteRecursive();
}
protected override void deleteRecursive()
{
Directory.Delete(Path, true);
}
public override void copy(FileItem destination)
{
if (!IsDirectory) File.Copy(destination.Path, Path, true);
else copyRecursive(destination);
}
protected override void copyRecursive(FileItem destination)
{
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
Path, destination.Path, true);
}
/// <summary>
/// Create's a LocalFileItem from a string path
/// </summary>
/// <param name="path"></param>
public LocalFileItem(String path)
: base(path)
{
}
/// <summary>
/// Creates a LocalFileItem from a FileSource path
/// </summary>
/// <param name="path"></param>
public LocalFileItem(FileSource path)
: base(path)
{
}
public override int CompareTo(object obj)
{
if (obj is FileItem)
{
FileItem fi = (FileItem)obj;
if (File.GetCreationTime(this.Path).CompareTo
(File.GetCreationTime(fi.Path)) > 0) return 1;
else if (File.GetCreationTime(this.Path).CompareTo
(File.GetCreationTime(fi.Path)) < 0) return -1;
else
{
if (File.GetLastWriteTime(this.Path).CompareTo
(File.GetLastWriteTime(fi.Path)) < 0) return -1;
else if (File.GetLastWriteTime(this.Path).CompareTo
(File.GetLastWriteTime(fi.Path)) > 0) return 1;
else return 0;
}
}
else
throw new ArgumentException("obj isn't a FileItem");
}
}
}
It seems you have misplaced the parameters in File.Copy(), it should be File.Copy(string source, string destination).
Also is "C:\Test2" a directory? You can't copy file to a directory.
Use something like that instead:
File.Copy(
sourceFile,
Path.Combine(destinationDir,Path.GetFileName(sourceFile))
);
I'm kinda guessing here, but could it be because:
You are trying to perform file operations in C: root? (there may be protection on this by Vista if you are using it - not sure?)
You are trying to copy to a non-existant directory?
The file already exists and may be locked? (i.e you have not closed another application instance)?
Sorry I cant be of more help, I have rarely experienced problems with File.Copy.
I was able to solve the problem, Michal pointed me to the right direction.
The problem was that I tried to use File.Copy to copy a file from one location to another, while the Copy method does only copy all the contents from one file to another(creating the destination file if it does not already exists). The solution was to append the file name to the destination directory.
Thanks for all the help!

Categories

Resources