|
Yeah, nobody is going to dig through all that code. Reduce it down to just the necessary parts and someone might take a look at it.
|
|
|
|
|
More paragraphs! (i.e. "Methods").
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Hi,
you seem to create one BackgroundWorker and reuse it over and over. Be aware that each time you execute a line such as
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
you ADD a handler to the event, so the second time the event fires, it will execute the same handler twice.
As this also applies to your line
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
I expect your BGW will duplicate its work and the number of results will behave quadratically.
There are several remedies:
1) you could remove the handlers with similar lines, say
bgw.RunWorkerCompleted -= new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
2) you could create a new BackgroundWorker each time;
3) but why not stuff all the work inside the bgw_DoWork method, and run the BackgroundWorker only once?
modified 24-Mar-17 10:37am.
|
|
|
|
|
|
I am creating a Xamarin app and I have to populate master data into sqlite DB on mobile.
I am new to OOPS and Xamarin
I have multiple requests to be made to get data from WebApi. The request I need to make is more than 50 calls to get info.
Now, I need to write async generic code to achieve this.
For example: I have to populate data for EmployeeMaster, Company Master etc..
My generic code should be able to identify which URL to call and Which object has to be returned. My normal code is as follows below
The only varying data are RestUrl and TodoItem
public async Task<list<todoitem>> RefreshDataAsync ()
{
Items = new List<todoitem> ();
RestUrl = "http://localhost:9054/TotoItem"
var uri = new Uri (string.Format (RestUrl, string.Empty));
try {
var response = await client.GetAsync (uri);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsStringAsync ();
Items = JsonConvert.DeserializeObject <list<todoitem>> (content);
}
} catch (Exception ex) {
Debug.WriteLine (@" ERROR {0}", ex.Message);
}
return Items;
}
|
|
|
|
|
Well, you're returning List<todoitem>, which is different from Task<list<todoitem>>.
It's also worth noting that your method, as written, will run synchronously despite your *Async() naming.
Convert the return type to List<todoitem> and rename your function and see what happens.
You likely also want to define variables in the method scope for Items and RestUrl. You also appear to have a typo in a string constant. Check the RestUrl variable.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Thank you Benjamin,
Even making the change will create a strong bond with todoitem. My intention is to make it generalised so that I can make a single method for making calls for different URL's and get data for different class object
As I have stated earlier I don't want to write the same code for a different URL request.
|
|
|
|
|
I tackled an issue similar to this a couple of years ago when I wrote, first this[^] article and then it's follow up here[^]. The architecture is a little bit convoluted so please take the time to read it and the code in the project files carefully.
This space for rent
|
|
|
|
|
Not a Benjamin, that's a quote.
You need to tack down the real basic fundamentals first; generics in C# are first class members and almost trivial.
But if you'd rather walk before crawling:
public async T RefreshData<T>(string url)
{
try
{
var response = await client.GetAsync (url);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsStringAsync ();
var items = JsonConvert.DeserializeObject<T>(content);
if(items != null)
{
return items;
}
throw new Exception($"Service did not provide a response formatted as type: {typeof(T)}");
}else{
throw new Exception($"Service request failure. Code: {response.StatusCode}");
}
}
catch (Exception ex)
{
Debug.WriteLine ($"ERROR {ex.Message}");
}
}
The $"" is the newfangled string interpolation BTW. Call with:
var myList = RefreshData<List<todoitem>>("http ://localhost:9054/TotoItem");
I had to throw an extra space in the string as the C# preformat is throwing in an anchor tag.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
Nathan Minier wrote: you're returning List<todoitem>, which is different from Task<List<todoitem>>. It's an async method, so that's perfectly normal.
Nathan Minier wrote: your method, as written, will run synchronously Nope:
var response = await client.GetAsync (uri);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks a lot Nathan Minier and Richard Deeming for the solution.
I will try to implement same solution and check
|
|
|
|
|
I'm sorry Richard, that's not correct.
Using the async keyword can mean that you want to return a Task that is not yet resolved, but doesn't necessarily mean that. It can simply mean that you're coalescing an asynchronous operation into a synchronous context, which is precisely what "await" does.
Using the await keyword means that you want to use the value provided by Task.Result, not the Task itself. It blocks execution of the method (ie runs synchronously) until the awaited Task is completed. That means that while the method is flagged as async, it resolves async operations into a synchronous context. I understand that the terminology is a bit misleading and the documentation does not help. But the fact is that if you're blocking the thread, you are running synchronously.
If the method were run asynchronously, it would look more like this:
public async Task<T> RefreshData<T>(string url)
{
return Task<T>.Run(()=>
{
var response = await client.GetAsync (url);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsStringAsync ();
var items = JsonConvert.DeserializeObject<T>(content);
if(items != null)
{
return items;
}
throw new Exception($"Service did not provide a response formatted as type: {typeof(T)}");
}else{
throw new Exception($"Service request failure. Code: {response.StatusCode}");
}
})
.ContinueWith(ex => { Debug.WriteLine ($"ERROR {ex.Message}");}, TaskContinuationOptions.OnlyOnFaulted));
}
I just didn't want to confuse the poor guy with Task execution and moving between synchronous and asynchronous contexts when he doesn't even have generics down.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
No, sorry, that's not correct.
The await client.GetAsync(url) and await response.Content.ReadAsStringAsync() calls will not block the current thread. They will sign up the rest of the method as a continuation, which will be invoked when the returned Task<T> has completed.
The GetAsync and ReadAsStringAsync calls (eventually) use an IO completion port to receive notification when the request has completed.
That's the whole point of async / await .
The only thing your example is doing differently is that it's using a background thread to run the very first part of the method - the call to GetAsync . As a result, the rest of the method will not run on the captured execution context from the caller of RefreshData . But you could achieve the same result by adding .ConfigureAwait(false) to the end of the GetAsync and ReadAsStringAsync calls.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I was completely lazy with that sample and I accept that, but it was just to illustrate a point. I think the issue we're having is that we're discussing different contexts.
I'm talking about the code that I'm looking at. I can't see the calling code, so am therefore not addressing it, and that's the code you're talking about. I realize that internal conventions are not the same as generally accepted practice, and my point about the return type and naming convention was not relevant, so I accept proper chastisement there.
I think we can both agree that the code we're looking at, and just that code, will not behave in an asynchronous manner.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
But that's the point - it WILL behave in an asynchronous manner!
public async Task<List<todoitem>> RefreshDataAsync ()
{
Items = new List<todoitem> ();
RestUrl = "http://localhost:9054/TotoItem"
var uri = new Uri (string.Format (RestUrl, string.Empty));
try {
var response = await client.GetAsync (uri);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsStringAsync ();
Items = JsonConvert.DeserializeObject <List<todoitem>> (content);
}
} catch (Exception ex) {
Debug.WriteLine (@" ERROR {0}", ex.Message);
}
return Items;
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
var response = await client.GetAsync (uri);<br />
if (response.IsSuccessStatusCode) {
This is an synchronous pattern within the context of the method, which is the only code that we see. No other actions will be taken by the available code until this resolves. The lack of thread blocking is not the point, the code execution flow in the method is the same as if the thread were blocked.
The Task continuation is only of interest to the calling code so that it can treat it appropriately.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
The same argument applies to your "asynchronous" version:
public async Task<T> RefreshData<T>(string url)
{
return Task<T>.Run(()=>
{
var response = await client.GetAsync (url);
...
})
.ContinueWith(ex => { Debug.WriteLine ($"ERROR {ex.Message}");}, TaskContinuationOptions.OnlyOnFaulted));
}
You've just moved the "logically synchronous" part to a lambda method, at the expense of making the outer method more complicated.
Adding the *Async suffix to a task-returning method is the recommended naming convention. Adding an extra Task.Run for extra asynchronicity doesn't really achieve anything. It's only going to have any effect if your method has with a long-running synchronous block before the first await call, and Task.Yield would probably be a better solution for that.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
As I said: it was a bad, rushed example. I will continue to accept bads on that.
"There are three kinds of lies: lies, damned lies and statistics."
- Benjamin Disraeli
|
|
|
|
|
hello guys i have windows form having three dialog box which dispaly proper in win 8 but when i run the same application in windows 10 my forms dialog box have space between each other an its look very ugly
can any one tell me how should i give same look & feel in windows 10 also i mean i run my form in any of win 10 or 8 it should display proper look (without space in dialog box).
|
|
|
|
|
Pick "Windows Classic" in Control Panel on both systems and you should be good to go.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
|
Ask the manufacturer for the technical documentation.
|
|
|
|
|
|
To give you an answer is difficult because of 2 reasons :
- at first : your answer is not very useful ...
- second : I suppose that most of us doesn't know your device. I don't know it too.
But following Suggestion :
Look for the Vendor-ID of your device.
Try to find out if you get get with this ID Information inside the Registry of your System which tells you if the device is currently connected and which Com-Ports are assigned. Most of the USB-Devices I know are writing Information like this into the Registry.
In this case I could give you a Sample-code which allows you to read this Information into your Application ...
But now it's up to you ...
|
|
|
|
|
Com port lists are a Windows registry function; nothing to do with what is actually hooked up (or not).
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|