WPF application + command line arguments - wpf

I am trying to process command line arguments for my WPF application for this I have made following changes
I have converted the output type as - Console Application
commented the StartupUri parameter in App.xaml
and override the
protected override void OnStartup(StartupEventArgs e)
{ }
Here is my overridden method
public partial class App : Application
{
[DllImport("Kernel32.dll")]
public static extern bool AttachConsole(int processId);
[DllImport("Kernel32.dll")]
public static extern bool FreeConsole();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
if (e.Args != null && e.Args.Length > 0)
{
ExecutionMethod.CommandLine = true;
ProcessCommandLineArgs.ProcessArgs(e.Args);
base.Shutdown();
}
else
{
FreeConsole();
ExecutionMethod.CommandLine = false;
TestApp WindowToDisplay = new TestApp();
WindowToDisplay.Show();
}
}
}
I am able to process the arguments and display the result on console.
But the issues is
This TestApp, creates process, say P1 , which execute some commands and result gets re-directed to console output.
Before P1 completes, main process exited due to base.Shutdown() in above overridden method.
How I can make this base.shutdown to wait for Process P1 to finish.
Any link/suggestions
Regards

I was actually waiting for new process, P1, to exit.
I synchronized main process and process P1.
Making ProceedForShutdwon to true only when process P1 gets exited
while (ExecutionMethod.ProceedForShutDown == false)
{
mut.WaitOne(500); // wait for 500 ms
}
base.Shutdown();
I am able to achieve my goal.
Hope this will help others also.

Related

Enable only one instance of WPF application

I have WPF allocation and I want to be able to open only one instance of my application.
So i have this 2 classes:
public sealed class SingleInstance
{
public static bool AlreadyRunning()
{
bool running = false;
try
{
// Getting collection of process
Process currentProcess = Process.GetCurrentProcess();
// Check with other process already running
foreach (var p in Process.GetProcesses())
{
if (p.Id != currentProcess.Id) // Check running process
{
if (p.ProcessName.Equals(currentProcess.ProcessName) == true)
{
running = true;
IntPtr hFound = p.MainWindowHandle;
if (User32API.IsIconic(hFound)) // If application is in ICONIC mode then
User32API.ShowWindow(hFound, User32API.SW_RESTORE);
User32API.SetForegroundWindow(hFound); // Activate the window, if process is already running
break;
}
}
}
}
catch { }
return running;
}
}
And:
public class User32API
{
[DllImport("User32.dll")]
public static extern bool IsIconic(IntPtr hWnd);
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public const int SW_RESTORE = 9;
}
App.xaml:
protected override void OnStartup(StartupEventArgs e)
{
if (SingleInstance.AlreadyRunning())
App.Current.Shutdown(); // Just shutdown the current application,if any instance found.
base.OnStartup(e);
}
So with this solution only one instance is allow but in case the user try to open another instance i can see that in the task bar i have new icon of my application, this icon automatically close when the mouse is over but I want to prevent this icon to be show so I remove this from App.xaml:
StartupUri="MainWindow.xaml"
And now my application not started (probably started but i cannot see it).
Any chance to achieve what I want ?
I need to call MainWindow but I don't know from where
UPDATE
So I try this approach:
protected override void OnStartup(StartupEventArgs e)
{
if (SingleInstance.AlreadyRunning())
App.Current.Shutdown(); // Just shutdown the current application,if any instance found.
base.OnStartup(e);
new MainWindow().Show();
}
And still i can see the second (and third and so...) icons when the user try to open another instance

How to properly canalize multithreaded message flow in a single threaded service?

In a WPF application, I have a 3rd party library that is publishing messages.
The messages are like :
public class DialectMessage
{
public string PathAndQuery { get; private set; }
public byte[] Body { get; private set; }
public DialectMessage(string pathAndQuery, byte[] body)
{
this.PathAndQuery = pathAndQuery;
this.Body = body;
}
}
And I setup the external message source from my app.cs file :
public partial class App : Application
{
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
}
private static void MessageReceived(Message message)
{
//handle message
}
}
These messages can be publishing from multiple thread at a time, making possible to call the event handler multiple times at once.
I have a service object that have to parse the incoming messages. This service implements the following interface :
internal interface IDialectService
{
void Parse(Message message);
}
And I have a default static instance in my app.cs file :
private readonly static IDialectService g_DialectService = new DialectService();
In order to simplify the code of the parser, I would like to ensure only one message at a time is parsed.
I also want to avoid locking in my event handler, as I don't want to block the 3rd party object.
Because of this requirements, I cannot directly call g_DialectService.Parse from my message event handler
What is the correct way to ensure this single threaded execution?
My first though is to wrap my parsing operations in a Produce/Consumer pattern. In order to reach this goal, I've try the following :
Declare a BlockingCollection in my app.cs :
private readonly static BlockingCollection<Message> g_ParseOperations = new BlockingCollection<Message>();
Change the body of my event handler to add an operation :
private static void MessageReceived(Message message)
{
g_ParseOperations.Add(message);
}
Create a new thread that pump the collection from my app constructor :
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
Task.Factory.StartNew(() =>
{
Message message;
while (g_ParseOperations.TryTake(out message))
{
g_DialectService.Parse(message);
}
});
}
However, this code does not seems to work. The service Parse method is never called.
Moreover, I'm not sure if this pattern will allow me to properly shutdown the application.
What have I to change in my code to ensure everything is working?
PS: I'm targeting .Net 4.5
[Edit] After some search, and the answer of ken2k, i can see that I was wrongly calling trytake in place of take.
My updated code is now :
private readonly static CancellationTokenSource g_ShutdownToken = new CancellationTokenSource();
private static void MessageReceived(Message message)
{
g_ParseOperations.Add(message, g_ShutdownToken.Token);
}
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
Task.Factory.StartNew(() =>
{
while (!g_ShutdownToken.IsCancellationRequested)
{
var message = g_ParseOperations.Take(g_ShutdownToken.Token);
g_DialectService.Parse(message);
}
});
}
protected override void OnExit(ExitEventArgs e)
{
g_ShutdownToken.Cancel();
base.OnExit(e);
}
This code acts as expected. Messages are processed in the correct order. However, as soon I exit the application, I get a "CancelledException" on the Take method, even if I just test the IsCancellationRequested right before.
The documentation says about BlockingCollection.TryTake(out T item):
If the collection is empty, this method immediately returns false.
So basically your loop exits immediately. What you may want is to call the TryTake method with a timeout parameter instead, and exit your loop when a mustStop variable becomes true:
bool mustStop = false; // Must be set to true on somewhere else when you exit your program
...
while (!mustStop)
{
Message yourMessage;
// Waits 500ms if there's nothing in the collection. Avoid to consume 100% CPU
// for nothing in the while loop when the collection is empty.
if (yourCollection.TryTake(out yourMessage, 500))
{
// Parses yourMessage here
}
}
For your edited question: if you mean you received a OperationCanceledException, that's OK, it's exactly how methods that take a CancellationToken object as parameter must behave :) Just catch the exception and exit gracefully.

should free the thread object? C#

public partial class MainWindow : window
{
private Thread t = new Thread;
private void btnSend_Click(object sender, RoutedEventArgs e)
{
if (t != null)
{
if (t.IsAlive == true)
{
t.Abort();
t = null; //Is this correct? should I free this before making null?
return;
}
t = new Thread(send.Image);
t.Start();
}
}
}
The above code shows an event handler. When I press a button called 'Send' new process should be created. and when I click the same button, process should stop. Then again I will press 'Send' and the process should start again. The thread should be created in same object 't'.
The benefit of de-referencing the Thread is that you allow the GC to collect any data the Thread class holds however you permanently stop the thread when you call Abort. As the thread class does not implement IDisposable there is no way to deterministically release any unmanaged resources held by the class, we hope Abort will do that.
The Thread class is fairly light weight and unless you have many MainWindows running at the same it will probably not impact your memory consumption. However it is good practice to be de-reference your objects if you know you will never use them again.
It is technically ok to do so, but you would have to do it this way:
private Thread t; // initially null
private void btnSend_Click(object sender, RoutedEventArgs e)
{
if (t != null)
{
t.Abort();
t = null;
}
else
{
t = new Thread(send.Image);
t.Start();
}
}
Also, it is perhaps no good design to call Abort.
You might instead implement your thread method in a way that it cyclically checks for a WaitHandle. This enables the thread to terminate in a controlled manner:
private Thread t; // initially null
private AutoResetEvent waitHandle = new AutoResetEvent(false);
private void btnSend_Click(object sender, RoutedEventArgs e)
{
if (t != null)
{
waitHandle.Set(); // signal thread termination
t = null;
}
else
{
t = new Thread(ThreadMethod);
t.Start();
}
}
private void ThreadMethod()
{
TimeSpan waitTime = TimeSpan.FromSeconds(1);
while (!waitHandle.WaitOne(waitTime))
{
// do something
}
}

Dynamic Threading with Start, Pause and Stop event handling

I have created sample application and implemented threading. basically aim to craete this application is i would like to
If any process(s) are runnig then User Interface should Notify
[DONE]
Handle dynamically created thread with ProgressBar [DONE]
Provide addition functionality to Start, Pause and Stop thread from
available progress list. [NEED YOUR HELP]
Note:- I don't have much knowledge about Threading and Delegates, so please let me know best solution for existing code.
Files and Controls are used:-
Basically three files are used in this demo application
ProgressForm.cs (Window Form)
which conatains Button for creating new progress and Container whic will hold all the created progressbars
ProgressClass.cs
Which contains Dynamic Threading and Delegates to Notify UI without locking or hanging user interface
ProgressControl.cs (User Control)
Which contains
Progressbar (to display process done)
Precent Label (display percentage of completed progress)
Start/Pause button (for play/pause a thread)
Stop button (stop running thread and remove progress from list)
StartTime Label (display process started time)
EndTime label (display time of process completed)
MaxValue Lable (generate random number between 25 to 100)
CODE SNIPPET:-
1. ProgressForm .cs
public partial class ProgressForm : Form
{
Random randomMaxValue = new Random();
public ProgressForm()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
ProgressClass m_clsProcess;
ProgressControl progress = new ProgressControl();
progress.StartedAt = DateTime.Now;
progress.MinValue = 0;
progress.CurrentValue = 0;
progress.MaxValue = randomMaxValue.Next(25, 100);
AddControl(progress);
m_clsProcess = new ProgressClass(progress, this, new ProgressClass.NotifyProgress(DelegateProgress));
m_clsProcess.Start();
}
private void DelegateProgress(int CurrentValue, ProgressControl Progress)
{
ProgressBar p = (ProgressBar)Progress.Controls.Find("pgbPercent", false)[0];
p.Minimum = Progress.MinValue;
p.Value = CurrentValue;
p.Maximum = Progress.MaxValue;
Label percent = (Label)Progress.Controls.Find("lblPercent", false)[0];
percent.Text = string.Format("{0:#00} %", Convert.ToInt16((CurrentValue * 100) / Progress.MaxValue));
Label start = (Label)Progress.Controls.Find("lblStart", false)[0];
start.Text = string.Format("{0:HH:mm:ss}", Progress.StartedAt);
if (CurrentValue == Progress.MaxValue)
{
Label complete = (Label)Progress.Controls.Find("lblComplete", false)[0];
complete.Text = string.Format("{0:HH:mm:ss}", DateTime.Now);
Progress.Status = ProgressControl.ProgressStatus.Completed;
}
Label max = (Label)Progress.Controls.Find("lblMaxValue", false)[0];
max.Text = string.Format("{0:#00}", Progress.MaxValue);
Button btnstartstop = (Button)Progress.Controls.Find("btnStartStop", false)[0];
btnstartstop.Click += new EventHandler(ProgressStartStop);
}
private void AddControl(Control ctl)
{
tableLayoutPnl.RowCount += 1;
tableLayoutPnl.RowStyles.Add(new RowStyle());
ctl.Dock = DockStyle.Fill;
tableLayoutPnl.Controls.Add(ctl, 0, tableLayoutPnl.RowCount - 1);
}
void ProgressStartStop(object sender, EventArgs e)
{
Button btn = sender as Button;
//
//Here i would like to write a code for START / PAUSE thread and update Image acording too.
//
}
}
2. ProgressControl.cs
public partial class ProgressControl : UserControl
{
public enum ProgressStatus
{
Initialize,
Running,
Paused,
Completed
}
public DateTime StartedAt { get; set; }
public DateTime CompletedAt { get; set; }
public int MinValue { get; set; }
public int CurrentValue { get; set; }
public int MaxValue { get; set; }
public ProgressStatus Status { get; set; }
public ProgressControl()
{
InitializeComponent();
this.Status = ProgressStatus.Initialize;
}
}
3. ProgressClass.cs
public class ProgressClass
{
private int ThreadWaitTime = 100;
private ProgressControl m_progress;
private NotifyProgress m_clsNotifyDelegate;
private System.Threading.Thread m_clsThread;
private System.ComponentModel.ISynchronizeInvoke m_clsSynchronizingObject;
public delegate void NotifyProgress(int PercentComplete, ProgressControl Progress);
public ProgressClass(ProgressControl Progress, System.ComponentModel.ISynchronizeInvoke SynchronizingObject, NotifyProgress NotifyDelegate)
{
m_progress = Progress;
m_clsSynchronizingObject = SynchronizingObject;
m_clsNotifyDelegate = NotifyDelegate;
}
public void Start()
{
m_clsThread = new System.Threading.Thread(DoProcess);
m_clsThread.Name = "Background Thread";
m_clsThread.IsBackground = true;
m_progress.Status = ProgressControl.ProgressStatus.Running;
m_clsThread.Start();
}
private void DoProcess()
{
for (int i = m_progress.MinValue; i <= m_progress.MaxValue; i++)
{
NotifyUI(i);
Thread.Sleep(ThreadWaitTime);
}
}
private void NotifyUI(int Value)
{
object[] args = new object[2];
args[0] = Value;
args[1] = m_progress;
m_clsSynchronizingObject.Invoke(m_clsNotifyDelegate, args);
}
}
I am not asking for write whole code instead of provide hint.
I would like to start/pause relevent thread from list, os what should i do for that?
I would like hind in following function:
void ProgressStartStop(object sender, EventArgs e)
{
Button btn = sender as Button;
//Here i would like to write a code for START / PAUSE thread and update Image acording too.
}
UPDATED:
You will want to use a ManualResetEvent or ManualResetEventSlim to create the pause and resume behavior in the thread. The idea is to check the state of the event in the worker thread at safe points. This is done via the WaitOne or Wait methods. If the event is signaled then the calls will return immediately allowing the thread to proceed. If the event is unsignaled then the calls block until the event is signaled via the Set method. So to pause the thread you would call Reset to unsignal the event and to resume the thread you would call Set.
Just remember to place calls to WaitOne or Wait at safe points in the instruction sequence of the worker thread. In other words, do not call these methods inside a lock or something like that. At the beginning or end of a loop is often a good start.
Also, it looks like you use the Invoke method for updating the UI. That is all fine and good, but for simply updating the UI with progress information there is a better option. It is better to publish the progress information to a shared data structure and then have the UI thread pick it up via a timer. For those that monitor my answers I harp about this a lot, I know. But, this strategy has a lot of advantages.
It breaks the tight coupling between the UI and worker threads that Invoke imposes.
It puts the responsibility of updating the UI thread on the UI thread where it should belong anyway.
The UI thread gets to dictate when and how often the update should take place.
There is no risk of the UI message pump being overrun as would be the case with the marshaling techniques initiated by the worker thread.
The worker thread does not have to wait for an acknowledgement that the update was performed before proceeding with its next steps (ie. you get more throughput on both the UI and worker threads).
It avoids the subtle race conditions that can occur when trying to gracefully end the worker thread.
It is more efficient since Invoke is an expensive operation.
Update:
Here is the general idea regarding the changes that could be made to ProgressStartStop.
private Dictionary<int, ThreadInfo> threads = new Dictionary<int, ThreadInfo>();
void ProgressStartStop(object sender, EventArgs e)
{
Button button = sender as Button;
int index = GetThreadIndexFromButton(button);
if (!threads.ContainsKey(index))
{
// The thread has not been started yet so do it now.
var thread = new Thread(RunThread);
thread.Start();
var mres = new ManualResetEventSlim(true);
var info = new ThreadInfo { Thread = thread, ProceedSignal = mres };
threads.Add(index, info);
// Change the button image here.
}
else
{
ThreadInfo info = threads[index];
if (info.ProceedSignal.Wait(0))
{
// The event is signaled which means the thread is running. Pause it.
info.ProceedSignal.Reset();
// Change the button image here.
}
else
{
// The event is unsignaled which means the thread is paused. Resume it.
info.ProceedSignal.Set();
// Change the button image here.
}
}
}
private class ThreadInfo
{
Thread Thread { get; set; }
ManualResetEventSlim ProceedSignal { get; set; }
}
It is generally considered bad practice to Suspend threads (though it is possible). The right way to pause and terminate threads is through the cooperation with the job that the thread is doing. The job should check a variable in a loop, and pause or exit accordingly. The controlling program can set that variable, and if you need feedback the background thread can call a notification method before exiting or sleeping.

OpenNetCF FTP class multithreading question

Currently, I have something like:
public partial class Form1 : Form
{
delegate void StringDelegate(string value);
private FTP m_ftp;
public Form1()
{
InitializeComponent();
}
private void connect_Click(object sender, EventArgs e)
{
OnResponse("Connecting");
m_ftp = new FTP(server.Text);
m_ftp.ResponseReceived += new FTPResponseHandler(m_ftp_ResponseReceived);
m_ftp.Connected += new FTPConnectedHandler(m_ftp_Connected);
m_ftp.BeginConnect(user.Text, password.Text);
}
void m_ftp_Connected(FTP source)
{
// when this happens we're ready to send command
OnResponse("Connected.");
}
void m_ftp_ResponseReceived(FTP source, FTPResponse Response)
{
OnResponse(Response.Text);
}
private void OnResponse(string response)
{
if (this.InvokeRequired)
{
this.Invoke(new StringDelegate(OnResponse), new object[] { response } );
return;
}
}
private void getFileList_Click(object sender, EventArgs e)
{
FTPFiles files = m_ftp.EnumFiles();
fileList.Items.Clear();
foreach (FTPFile file in files)
{
fileList.Items.Add( new ListViewItem( new string[] { file.Name, file.Size.ToString() } ));
}
tabs.SelectedIndex = 1;
}
private void upload_Click(object sender, EventArgs e)
{
FileStream stream = File.OpenRead("\\My Documents\\My Pictures\\Waterfall.jpg");
m_ftp.SendFile(stream, "waterfall.jpg");
stream.Close();
}
Which works fine - this example was taken from the samples. However, after a recent re-visit I have a question. In this particular case since OnResponse() function doesn't update the UI, it seems to serve no purpose here. I removed it (as well as all the calls to it) and it still works like before. Am I missing something?
After reading up more about multi threading with forms, I came to understand that this mechanism (demonstrated in the code above) is there to make sure the UI is responsive.
So in case when we need to say, update a UI element (such as textbox, label etc) we would have OnResponse implemented as follows:
delegate void StringDelegate(string dummy);
void OnResponse(string dummy)
{
if(!InvokeRequired)
{
button1.Text = dummy;
}
else
Invoke(new StringDelegate(OnResponse),new object[] {enabled});
}
If this function is implemented as:
delegate void StringDelegate(string dummy);
void OnResponse(string dummy)
{
if(InvokeRequired)
{
Invoke(new StringDelegate(OnResponse),new object[] {dummy});
return;
}
}
What's the use to have it at all? Is it absolutely necessary?
And another question: is ftp object running on its own thread here?
The FTP object is definitely running on its own thread. How do I know? This line:
m_ftp.BeginConnect(user.Text, password.Text);
This is an asynchronous method. Once you call this, the FTP component will use a thread from the .NET threadpool to do all of the work. This dedicated thread is the one that is used to "raise" the events. Ultimately a "raised event" is just one or more method calls to all of the delegates added to the event invocation list; it is this dedicated thread spun up by the Begin method that calls these methods. This thread is not the same thread as the thread that runs the UI, hence the need for the Invoke calls.
If you want the FTP component to use the UI thread, you'd use the Connect method instead of the BeginConnect method. This means your events wont work either, nor will your UI respond to interaction - this is completely expected because a thread can only do one thing at a time: it's either servicing the UI, or executing the FTP code. This is why you need a 2nd thread.
Make sense?
-Oisin

Resources