I have silverlight application which is having Current time and date , ia m getting this from WCF Service now i want to update Current Date and time in every minute.
How to achieve that ?
My service code is :
[OperationContract]
public DateTime GetDateTime()
{
return DateTime.Now ;
}
My xaml.cs is :
void Welcome_Loaded(object sender, RoutedEventArgs e)
{
SessionService.SLWebServiceClient client = new SessionService.SLWebServiceClient();
client.GetDateTimeCompleted += new EventHandler<SessionService.GetDateTimeCompletedEventArgs>(client_GetDateTimeCompleted);
client.GetDateTimeAsync();
}
void client_GetDateTimeCompleted(object sender, SessionService.GetDateTimeCompletedEventArgs e)
{
lblDateTime.Text = e.Result.ToString();
}
Thanks.
You may use a DispatcherTimer to call the WCF service every two minutes. Here's how:
// Every 2 minutes calls the timer_Tick handler
DispatcherTimer timer = new DispatcherTimer() { Interval = new TimeSpan(0, 2, 0) };
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
private void timer_Tick(object sender, EventArgs e)
{
SessionService.SLWebServiceClient client = new SessionService.SLWebServiceClient();
client.GetDateTimeCompleted += new EventHandler<SessionService.GetDateTimeCompletedEventArgs>(client_GetDateTimeCompleted);
client.GetDateTimeAsync();
}
Hope it helps!
Bruno
Related
I can't update my WinForm label properties.
Details: I am trying to check my database and get some values posted, but I can't even update a mere label it seems. I'm using SharpDevelop.
The code:
//this is my form
public partial class MainForm : Form
{
//Declaring timer
public static System.Timers.Timer aTimer = new System.Timers.Timer();
public MainForm()
{
InitializeComponent();
//Timer
aTimer.Elapsed +=new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000; //milisecunde
aTimer.Enabled = true;
label1.Text="some_text";
}
private static void OnTimedEvent(object source, ElapsedEventArgs e) {Check();}
public static void Check()
{
//Database checks here..
try{label1.Text="new_text";}catch(Exception e) {MessageBox.Show(e.ToString());}
MessageBox.Show("BAAAA");
}
void Button1Click(object sender, EventArgs e)
{
label1.Text = "mergeeeeee?!";
}
}
EDIT: I've removed all static modifiers. Also updated the post with the new code (try catch is added and the messagebox after it + a button that changes the label).
The try catches the following error:
. Really could use some help, been researching answers for more than 6 hours.
Try this (use a System.Windows.Forms.Timer instead of System.Timers.Timer):
//Declaring timer
public System.Windows.Forms.Timer aTimer = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
//Timer
aTimer.Tick += aTimer_Tick;
aTimer.Interval = 2000; //milisecunde
aTimer.Enabled = true;
label1.Text = "some_text";
}
void aTimer_Tick(object sender, EventArgs e)
{
Check();
}
public void Check()
{
try
{
//Database checks here..
label1.Text = string.Format("new_text {0}", DateTime.Now.ToLongTimeString());
}
catch (Exception ex)
{
throw ex;
}
MessageBox.Show("BAAAA");
}
The Elapsed event of the System.Timers.Timer is fired on a non-UI thread (change your original code to not swallow exceptions and you should see the cross-thread exception).
I used the following code for my project and it worked.
It has a button to activate the timer and the timer raises an event when 500 milliseconds passed.
private void ActiveTimer_Click(object sender, EventArgs e)
{
EnableTimer();
}
private void EnableTimer()
{
System.Timers.Timer raiseTimer = new System.Timers.Timer();
raiseTimer.Interval = 500;
raiseTimer.Elapsed += RaiseTimerEvent;
raiseTimer.AutoReset = true;
raiseTimer.Enabled = true;
}
private void RaiseTimerEvent(object sender, System.Timers.ElapsedEventArgs e)
{
this.Invoke(new Action(() =>
{
label1.Text += "500 ms passed\n";
}));
}
I have a BackgroundWorker on my WPF UserControl.
private readonly BackgroundWorker worker = new BackgroundWorker();
public ucCustomer()
{
InitializeComponent();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// run all background tasks here
System.Threading.Thread.Sleep(10000);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//update ui once worker complete his work
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
Above code is work, the UI is response when the task is working, but if i change the worker_DoWork() to
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// run all background tasks here
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(() => {
gridDataBind(); //A long data-mining task,using Dispatcher.Invoke() to access UI.
}));
}
private void gridDataBind()
{
SnEntities sn = new SnEntities();
var customers = from c in sn.Customer select c;
dgCustomer.ItemsSource = customers.ToList();
}
The UI is freeze until the task is end.
Is it any solution?
Thanks you.
Try setting the ItemsSource like below code:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// run all background tasks here
e.Result = gridDataBind(); //A long data-mining task.
}
private IList<Customer> gridDataBind()
{
SnEntities sn = new SnEntities();
var customers = from c in sn.Customer select c;
return customers.ToList();
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
var customers = e.Result as IList<Customer>;
ObservableCollection<Customer> gridItemsSource = new ObservableCollection<Customer>();
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(() =>
{
dgCustomer.ItemsSource = gridItemsSource;
}));
foreach(var customer in customers)
{
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
new Action(() =>
{
gridItemsSource.Add(customer);
}));
}
}
Store your data in e.result at worker_DoWork and update UI at the worker_RunWorkerCompleted.
in that case UI will be free when data will coming from database.
Try this, it should help you
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => gridDataBind();));
It is possible to detect a touch press and hold gesture with the MouseRightButtonDown event. Unfortunately it fires not until I release my finger from the screen. This is to late!
Does anyone have ideas? Thanks in advance.
It is possible to do that in an awaitable fashion. Create a timer with specific interval. Start it when user tapped and return the method when timer elapsed. If user release the hand, return the method with false flag.
public static Task<bool> TouchHold(this FrameworkElement element, TimeSpan duration)
{
DispatcherTimer timer = new DispatcherTimer();
TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
timer.Interval = duration;
MouseButtonEventHandler touchUpHandler = delegate
{
timer.Stop();
if (task.Task.Status == TaskStatus.Running)
{
task.SetResult(false);
}
};
element.PreviewMouseUp += touchUpHandler;
timer.Tick += delegate
{
element.PreviewMouseUp -= touchUpHandler;
timer.Stop();
task.SetResult(true);
};
timer.Start();
return task.Task;
}
For more information, read this post.
Great piece of code. I add just an example usage for completeness:
private async void btn_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (await TouchHold(btn, TimeSpan.FromSeconds(2)))
{
// todo: long press code goes here
}
}
And from XAML:
<Button Name="btn" PreviewMouseDown="btn_PreviewMouseDown">Press long</Button>
Use the Hold gesture provided by Blake.NUI toolkit
Either a button or label or image, we can use the MouseDown and MouseUp for starting the delay and Stopping the delay.
For MouseDown,
// Declaration of timer and timercount
int timerCount = 0;
DispatcherTimer dt = new DispatcherTimer();
public myConstructor()
{
dt.Interval = new TimeSpan(0, 0, 1);
}
// Mouse Down Event
private void EnterHoldState(object sender, TouchEventArgs e)
{
timerStarted();
}
//Mouse Up event
private void ExitHoldState(object sender, RoutedEventArgs e)
{
timerStopped();
}
// Stops the timer and resets the timer count to 0
private void timerStopped()
{
dt.Stop();
timerCount = 0;
}
// Starts the timer and sets delayCounter function for counting the delay seconds and acts on it
private void timerStarted()
{
dt.Tick += delayCounter;
dt.Start();
}
//Once delay timer reaches 2 seconds, the button navigates to nextpage.
private void delayCounter(object sender, EventArgs e)
{
timerCount++;
if (timerCount == 2)
{
this.NavigationService.Navigate(new nextPage());
}
}
I recently had to implement a Button where I needed to it to trigger after being pressed for five seconds.
To do this I created an attached behavior. I have the five seconds backed into the behavior as I did not need this configurable but easily done with a Dependency Property and it is hooked up to be used with a Command in an MVVM way but it could easily be changed to trigger Click.
<Button Command="{Binding Path=ButtonCommand}">
<i:Interaction.Behaviors>
<behaviors:PressAndHoldBehavior />
</i:Interaction.Behaviors>
</Button>
public sealed class PressAndHoldBehavior : Behavior<Button>
{
private DispatcherTimer dispatcherTimer;
protected override void OnAttached()
{
dispatcherTimer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(5)};
dispatcherTimer.Tick += OnDispatcherTimerTick;
AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
AssociatedObject.PreviewMouseLeftButtonUp += AssociatedObjectPreviewMouseLeftButtonUp;
}
protected override void OnDetaching()
{
dispatcherTimer.Stop();
dispatcherTimer.Tick -= OnDispatcherTimerTick;
dispatcherTimer = null;
AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
AssociatedObject.PreviewMouseLeftButtonUp -= AssociatedObjectPreviewMouseLeftButtonUp;
}
private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
dispatcherTimer.Start();
e.Handled = true;
}
private void AssociatedObjectPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
dispatcherTimer.Stop();
e.Handled = true;
}
private void OnDispatcherTimerTick(object sender, EventArgs e)
{
AssociatedObject.Command.Execute(null);
}
}
I'm working on building a multi-threaded UI. I would like long processes to be handled by the BackgroundWorker class, and have a small timer on the UI to keep track of how long the process is taking. It's my first time building such a UI, so I'm reading up on related resources on the web. My test code is thus:
private BackgroundWorker worker;
private Stopwatch swatch = new Stopwatch();
private delegate void simpleDelegate();
System.Timers.Timer timer = new System.Timers.Timer(1000);
string lblHelpPrevText = "";
private void btnStart_Click(object sender, RoutedEventArgs e)
{
try
{
worker = new BackgroundWorker(); //Create new background worker thread
worker.DoWork += new DoWorkEventHandler(BG_test1);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BG_test1end);
worker.RunWorkerAsync();
simpleDelegate del = new simpleDelegate(clockTicker);
AsyncCallback callBack = new AsyncCallback(clockEnd);
IAsyncResult ar = del.BeginInvoke(callBack, null);
lblHelpText.Text = "Processing...";
}
finally
{
worker.Dispose(); //clear resources
}
}
private void clockTicker()
{
//Grab Text
simpleDelegate delLblHelpText = delegate()
{ lblHelpPrevText = this.lblHelpText.Text; };
this.Dispatcher.BeginInvoke(DispatcherPriority.Send, delLblHelpText);
//Start clock
timer.Elapsed += new ElapsedEventHandler(clockTick);
timer.Enabled = true;
swatch.Start();
}
private void clockTick(object sender, ElapsedEventArgs e)
{
simpleDelegate delUpdateHelpTxt = delegate()
{ this.lblHelpText.Text = String.Format("({0:00}:{1:00}) {2}", swatch.Elapsed.Minutes, swatch.Elapsed.Seconds, lblHelpPrevText); };
this.Dispatcher.BeginInvoke(DispatcherPriority.Send, delUpdateHelpTxt);
}
private void BG_test1(object sender, DoWorkEventArgs e)
{
//this.lblHelpText.Text = "Processing for 10 seconds...";
Thread.Sleep(15000);
}
private void BG_test1end(object sender, RunWorkerCompletedEventArgs e)
{
this.lblHelpText.Text = "Process done.";
this.timer.Enabled = false;
this.swatch.Stop();
this.swatch.Reset();
}
static void clockEnd(IAsyncResult ar)
{
simpleDelegate X = (simpleDelegate)((AsyncResult)ar).AsyncDelegate;
X.EndInvoke(ar);
}
The idea is when the button is clicked, we take the status text from a Label (e.g. "Processing...") then append the time onto it every second. I could not access the UI elements from the Timer class as it's on a different thread, so I had to use delegates to get and set the text.
It works, but is there a better way to handle this? The code seems much for such a basic operation. I'm also not fully understanding the EndInvoke bit at the bottom. I obtained the snippet of code from this thread Should One Always Call EndInvoke a Delegate inside AsyncCallback?
I understand the idea of EndInvoke is to receive the result of BeginInvoke. But is this the correct way to use it in this situation? I'm simply worried about any resource leaks but when debugging the callback appears to execute before my timer starts working.
Don't use a separate timer to read the progress of your BackgroundWorker and update the UI. Instead, make the BackgroundWorker itself "publish" its progress to the UI directly or indirectly.
This can be done pretty much anyway you want to, but there's a built-in provision exactly for this case: the BackgroundWorker.ProgressChanged event.
private void BG_test1(object sender, DoWorkEventArgs e)
{
for(var i = 0; i < 15; ++i) {
Thread.Sleep(1000);
// you will need to get a ref to `worker`
// simplest would be to make it a field in your class
worker.ReportProgress(100 / 15 * (i + 1));
}
}
This way you can simply attach your own handler to ProgressChanged and update the UI using BeginInvoke from there. The timer and everything related to it can (and should) go.
You can use timer to update UI. It is normal practice. Just instead of System.Timer.Timer I suggest use System.Windows.Threading.DispatcherTimer. The DispatcherTimer runs on the same thread as the Dispatcher. Also, instead of BackgroundWorker you can use ThreadPool.
Here is my sample:
object syncObj = new object();
Stopwatch swatch = new Stopwatch();
DispatcherTimer updateTimer; // Assume timer was initialized in constructor.
void btnStart_Click(object sender, RoutedEventArgs e) {
lock (syncObj) {
ThreadPool.QueueUserWorkItem(MyAsyncRoutine);
swatch.Start();
updateTimer.Start();
}
}
void updateTimer_Tick(object sender, EventArgs e) {
// We can access UI elements from this place.
lblHelpText.Text = String.Format("({0:00}:{1:00}) Processing...", swatch.Elapsed.Minutes, swatch.Elapsed.Seconds);
}
void MyAsyncRoutine(object state) {
Thread.Sleep(5000);
lock (syncObj)
Dispatcher.Invoke(new Action(() => {
swatch.Stop();
updateTimer.Stop();
lblHelpText.Text = "Process done.";
}), null);
}
private void button1_Click(object sender, EventArgs e)
{
string strFullFilePath = #"D:\Print.pdf";
ProcessStartInfo ps = new ProcessStartInfo();
ps.UseShellExecute = true;
ps.Verb = "print";
ps.CreateNoWindow = true;
ps.WindowStyle = ProcessWindowStyle.Hidden;
ps.FileName = strFullFilePath;
Process.Start(ps);
Process proc = Process.Start(ps);
KillthisProcess("AcroRd32");
}
public void KillthisProcess(string name)
{
foreach (Process prntProcess in Process.GetProcesses())
{
if (prntProcess.ProcessName.StartsWith(name))
{
prntProcess.WaitForExit(10000);
prntProcess.Kill();
}
}
}
Hi i am calling a Async method with different parameter value multiple times giving same result in completed event.
client.ListAllLookupValuesByTypeCompleted += client_ListAllAddressFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");
client.ListAllLookupValuesByTypeCompleted += client_ListAllPhoneFormatCompleted;
client.ListAllLookupValuesByTypeAsync("PhoneFormat");
void client_ListAllAddressFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbAddressFormat.ItemsSource = e.Result;
}
void client_ListAllPhoneFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbPhonePrintFormat.ItemsSource = e.Result;
}
please help me.
Thanks.
You can create new instance of client.
...
var client = new XyzClient();
client.ListAllLookupValuesByTypeCompleted += client_ListAllAddressFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");
client = new XyzClient();
client.ListAllLookupValuesByTypeCompleted += client_ListAllPhoneFormatCompleted;
client.ListAllLookupValuesByTypeAsync("PhoneFormat");
...
void client_ListAllAddressFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbAddressFormat.ItemsSource = e.Result;
}
void client_ListAllPhoneFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbPhonePrintFormat.ItemsSource = e.Result;
}
Another solution would be to make the second call in the handler of the first one (probably creating new client instance anyway).