I have a form with a listview in it that the user can add tasks too. Then the user can click a button then the application goes through each task in the listview 1 by 1 an executes it.
These tasks are more like instructions that actually complete tasks.I do this by having a class with a loop in it that goes through each item and it then completes a task I set for each item(instruction). In order to start the parsing I have a button on a form that calls that function. IE: RunTask(listview1, 1) - basically all this does it starts the loop I have in my class , with a specified listview and which item to start on.
Everything works perfect except the screen locks up, so I cannot implement a stop feature to stop the application from parsing these listview items. I just don't understand how I can implement this without crossthreading, since the thread that I would like to run seperate will always access this listview. It is not feasable to redesign the program to get rid of the listview. I tried application.doevents although it caused way too man bugs. I have been researching for days on how to fix this but I have NO idea. Hopefully someone cans hed some light.
Also I had already added a background worker to solve the issue, although I had to obviously set checkforillegalcrossthreadcalls = false and I know this isn't smart.
Try doing something like this. Take you list view and turn it into a set of values that aren't UI related. Like this:
string[] values =
this
.listView1
.Items
.Cast<ListViewItem>()
.Select(x => x.Text)
.ToArray();
Then you can use the parallel task library to run your task in the background:
var tokenSource = new System.Threading.CancellationTokenSource();
var token = tokenSource.Token;
var task = System.Threading.Tasks.Task.Factory
.StartNew(() => RunTasks(values, 1), token);
If you need to cancel the task you can do this:
tokenSource.Cancel();
But to handle UI updates when the task is finished do this:
task.ContinueWith(r =>
{
/* When compete code */
});
Make sure that you invoke the UI updates so that they go on the UI thread.
My apologies that I didn't write this in VB.NET. My VB is getting rusty.
Related
When I use the method uiitem.WaitForControlExist(milliseconds); Execution waits too long. Muchmore of the specified parameter.
Any idea?
Just an example on UIMap.cs file:
public void AnyAlertClickNo(int seconds)
{
#region Variable Declarations
WinWindow uIAlert = this.UIAlertWindow;
WinButton uINoButton = this.UIAlertWindow.UIAnswerPanel.UINoButton;
#endregion
if(uIAlert.WaitForControlExist(seconds*1000)){
Mouse.Click(uINoButton, new Point(20, 10));
}
}
Te calls could be:
Any_UIMap aaa = new Any_UIMap();
aaa.AnyAlertClickNo(3);
I don't know why this code are waiting for this alert arround 15-20 seconds.
thanks in advance
The code is unlikely to be
uiitem.WaitForControlExist(milliseconds);
There are often several levels of UI control, so the code is more likely to be of the form:
UiMap.uiOne.uiTwo.uiThree.WaitForControlExist(milliseconds);
A line like the above has a meaning like the following, provided that it has the first use of the three UI controls:
var one = UiMap.uiOne.Find();
var two = one.uiTwo.Find();
two.uiThree.WaitForControlExist(milliseconds);
I suspect that your Coded UI test is spending some time on the ...Find() calls. You might do some diagnostics to check where the time is spent. Look here and here for some good ideas on speeding up Coded UI tests.
Well it is supposed to.
UITestControl.WaitForControlExist Method (Int32)
When the wait operation causes an implicit search for the control or, when the application is busy, the actual wait time could be more than the time-out specified.
My application works like this:
Upload Excel file + convert to DataTable
Start new thread
Begin loop through DataTable
Update UI (Label) to show "Processing row [i] of [n]"
Next
End loop
The bold is what I'm not able to do. I've looked around online for updating UI elements from worker threads, but all the results I can seem to find are for Windows Forms, rather than a web project. Is this possible?
yes, you can do it, and actually it is not difficult. you can use ajax toolbox to do it easily. simply use an updatepanel, and update progress.
check http://ajaxcontroltoolkit.codeplex.com/
an example: http://www.asp.net/ajax/documentation/live/overview/updateprogressoverview.aspx
I found a workaround using jQuery AJAX and asp.NET WebMethods and a session variable.
I used a method from one of my previous questions, by having a WebMethod check on a Session variable that was updated by the worker thread.
Worker thread:
Session["progress"] = "{\"current\":" + (i + 1) + ", \"total\":" + dt.Rows.Count + "}"
WebMethod:
[WebMethod]
public static string GetProgress()
if (HttpContext.Current.Session["progress"] == null) {
return "{\"current\":1,\"total\":1}";
} else {
return HttpContext.Current.Session["progress"];
}
}
my jQuery basically looped calling that AJAX WebMethod every second. It would start on page load and if the current = total then it would display "Completed" and clear the loop, otherwise it shows "Processing row [current] of [total]". I even added a jQuery UI Progressbar
This is kind of a manual solution but it solves my problem, with little overhead. An unexpected but nice piece is that since it is utilizing a Session variable, and the WebMethod checks on page load, if the worker thread is active then the progressbar will show even if you navigate away and come back to the page.
I have a little problem. I'm trying to add a timer job following this tutorial : http://dotnetfinder.wordpress.com/2010/07/24/creatingcustomsharepointtimerjob2010/
I came to the point where my timer job is enabled and is launching every five minutes.
The problem is that it doesn't execute all the Execute method.
public override void Execute(Guid contentDbId)
{
// get a reference to the current site collection's content database
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
// get a reference to the "ListTimerJob" list in the RootWeb of the first site collection in the content database
SPList Listjob = contentDb.Sites[0].RootWeb.Lists["Liens"];
// create a new list Item, set the Title to the current day/time, and update the item
SPListItem newList = Listjob.Items.Add();
//newList["URL"] = "http://"+DateTime.Now.ToString()+".fr";
//newList.Update();
}
I attached the debugger to the OWSTIMER.EXE.
If i try to add a breakpoint at the line : SPList ListJob = ..., it's ok,
But if i try to add a new breakpoint at the next line (SPListItem newList = ...) then i have the following message :
"The following breakpoint cannot be set : ...
The CLR was unable to set the breakpoint".
Does anyone has any idea how i can make it work ?
You seem to be attaching to the correct service. See How to: Debug a Timer Job to double check your steps.
Also, as pointed out in this comment, you should restart the timer service when deploying a timer job:
mark
February 11, 2011 at 4:41 am
There is a very important step that
needs to be completed with any Timer Project. You hav to recycle the
SharPoint timer service in between deployments. Best way to do this is
to add
net stop SPTimerV4 – Pre Build
net start SPTimerV4 – Post Build
to your sharepoint project. If you do not do the above – you will be
puzzled as to why your code seems not to be up to date. The reason is
that the timer service Caches the assembly with your class. This can
cost you hours of troubleshooting, in trying to identify why your code
does not deploy.
Make sure your project configuration is in Debug mode (in Release mode compiler is setting is enabled for optimized code). Refer to this blog post
What is a good case/example for using the ScheduledDisposable in Reactive Rx
I like the using the CompositeDisposable and SerialDisposable, but would you need the ScheduledDisposable.
The logic of using the Rx disposables is that code that performs some sort of set up operation can return an IDisposable that anonymously contains the code that will do the associated clean up at a later stage. If this pattern is used consistently then you can compose together many disposables to perform a single clean up operation without any specific knowledge of what is being cleaned up.
The problem is that if that clean up code needs to run on a certain thread then you need some way for Dispose called on one thread to be marshalled to required thread - and that's where ScheduledDisposable comes in.
The primary example is the SubscribeOn extension method which uses ScheduledDisposable to ensure that the "unsubscribe" (i.e. the Dispose) is run on the same IScheduler that the Subscribe was run on.
This is important for the FromEventPattern extension method, for example, that attaches to and detaches from event handlers which must happen on the UI thread.
Here's an example of where you might use ScheduledDisposable directly:
var frm = new SomeForm();
frm.Text = "Operation Started.";
var sd = new ScheduledDisposable(
new ControlScheduler(frm),
Disposable.Create(() =>
frm.Text = "Operation Completed."));
Scheduler.ThreadPool.Schedule(() =>
{
// Long-running task
Thread.Sleep(2000);
sd.Dispose();
});
A little contrived, but it should show a reasonable example of how you'd use ScheduledDisposable.
I'm using Symbian C++ to create my code, I'm using S60 5th Ed SDK
I want to know how to send different messages - Their body text not the same - to multiple recipients in a for-loop ?
I've tried the example below, but when I try to use it in a loop it crashes due to ActiveObjects properties, as I should wait to AO to finish before calling it again.
Sending_SMS_in_S60_3rd_Edition_MTM
Below is example of what I need to do:
SendSMSL(); // **I call this function once to start the process**
// **iRecepients is a CDesCArray contains phone numbers**
// ** iSMSBody is a CDesCArray contains each contact SMS body text**
void CSMS::SendSMSL()
{
if(iRecepients->Count() >= 1)
{
TInt x = iRecepients->Count()-1;
TInt y = iSMSBody->Count()-1;
// **If the sms validating and scheduling succeeded then delete last item from both arrays**
if(iSMSHandler->SendL((*iRecepients)[x],(*iSMSBody)[y])
{
iRecepients->Delete(x);
iSMSBody->Delete(y);
}
}
}
Now, in the code above I call iSMSHandler->SendL() which send sms using AO, and in iSMSHandler object RunL() function, I call back the function above CSMS::SendSMSL() , which in turn checks if there is still anymore iRecepients elements and then call again iSMSHandler->SendL() AO , and keeps this way till no more iRecepients.
Looking forward to hear your feedback on the modification above.
Many thanks in advance.
The link you posted doesn't work for me so I can't see the rest of the code.
Assuming that iSmsHandler is a class that uses active objects to send SMS messages,
I see several issues with your loop.
1) You need to wait for the first asynchronous SendL to complete before you can issue the next SendL
2) The buf variable can not go out of scope until the SendL completes. (This may be the reason for your crash)
I suggest that you keep the textbuffer somewhere else, like together with iSmsHandler, and then code the active object that is called when SendL completes to issue the next SendL.
All of this is guesses since I have no idea what class iSmsHandler is....