Okay so I'm still quite new to coding and mostly only knows the basics. I have never worked with API. I'm trying to make a program that gets the number of subs from PewDiePie and Cocomelon and compare them.
namespace PewdiepieVsCoco
{
class Program
{
static void Main(string[] args)
{
try
{
var len = args?.Length;
if (len == null || len.Value == 0)
{
PrintStart();
return;
}
var pdpSubCount = args[0];
var pdpSub = GetPDPSubcount(pdpSubCount).Result;
PrintPDPResult(pdpSub);
}
catch (AggregateException agg)
{
foreach (var e in agg.Flatten().InnerExceptions)
Console.WriteLine(e.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
private static async Task<dynamic> GetPDPSubcount(string pdpSubCount)
{
var parameters = new Dictionary<String, String>
{
["key"] = ConfigurationManager.AppSettings["APIKey"],
["channelsId"] = "UC-lHJZR3Gqxm24_Vd_AJ5Yw",
["part"] = "statistics",
["forUsername"] = "PewDiePie",
["fields"] = "items/statistics(subscriberCount)"
};
var baseUrl = "https://www.googleapis.com/youtube/v3/channels";
var fullUrl = MakeUrlWithQuery(baseUrl, parameters);
var pdpSub = await new HttpClient().GetStringAsync(fullUrl);
if (pdpSub != null)
{
//Does the thing
return JsonConvert.DeserializeObject(pdpSubCount);
}
return default(dynamic);
}
private static string MakeUrlWithQuery(string baseUrl,
IEnumerable<KeyValuePair<string, string>> parameters)
{
if (string.IsNullOrEmpty(baseUrl))
throw new ArgumentException(nameof(baseUrl));
if (parameters == null || parameters.Count() == 0)
return baseUrl;
return parameters.Aggregate(baseUrl,
(accumulated, kvp) => string.Format($"{accumulated}{kvp.Value}&"));
}
private static void PrintPDPResult(dynamic pdpSub)
{
Console.WriteLine($"PewDiePie currently have: {pdpSub} subscribers");//insert subs
}
private static void PrintStart()
{
Console.WriteLine("The war is on!");
Thread.Sleep(500);
Console.WriteLine("PewDiePie Vs Cocomelon – Nursery Rhymes");
Thread.Sleep(500);
}
}
}
Here is the code, I have followed what an Indian dude did in a YT video so some things I don't know what do but I have an idea on what's going on.
Your program is likely returning before making any API calls because you aren't executing it with any command line arguments. Remove this block of code, so it continues without returning early.
var len = args?.Length;
if (len == null || len.Value == 0)
{
PrintStart();
return;
}
Also, pdpSubCount should not be a function argument, and should not be passed into DeserializeObject. You should be deserializing the response from the api call
return JsonConvert.DeserializeObject(pdpSub)
Related
Hi I have Controller method as below
[HttpPost]
public JsonResult Post(string vehiclesString, string Entity, int EntityId, ApplicationUser CurrentUser)
{
//https://stackify.com/understanding-asp-net-performance-for-reading-incoming-data/
List<Vehicle> vehicles = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Vehicle>>(vehiclesString);
InputFieldController c = new InputFieldController();
var errors = new List<string>();
try
{
//let's get model for each of the input field
InputFieldController icController = new InputFieldController();
List<InputField> fields = icController.GetNamesValues("VehicleField", -1, "Vehicle", 0);
foreach (Vehicle vehicle in vehicles)
{
//convert array of strings into array of input fields
if (fields.Count != vehicle.ValueStrings.Count)
{
throw new Exception("Vehicle columns mismatch. Expected "
+ fields.Count + " fields, but received " + vehicle.ValueStrings.Count);
}
for (int i = 0; i < fields.Count; i++)
{
InputField field = fields[i];
string cell = vehicle.ValueStrings[i];
if ((cell != null || cell != String.Empty) && (field.Type == "radio" || field.Type == "dropdown"))
{
var f = field.InputDropdowns.Where(x => x.Name == cell).FirstOrDefault();
if (f != null)
{
field.InputValue.InputDropdownId = f.InputDropdownId;
}
else
field.InputValue.InputDropdownId = null;
}
else
{
field.InputValue.Value = cell;
}
vehicle.Values.Add(field);
}
vehicle.Blob = Newtonsoft.Json.JsonConvert.SerializeObject(vehicle.Values);
Vehicle v = new Vehicle();
if (vehicle.VehicleId == 0)
{
v = this.DomainLogicUnitOfWork.VehicleManager.Create(vehicle, Entity, EntityId);
}
}
JsonResult data = Json(new
{
success = true,
});
List<Vehicle> vehiclesList = this.DomainLogicUnitOfWork.VehicleManager.List(Entity, EntityId);
if (vehiclesList != null)
foreach (Vehicle v in vehiclesList)
{
if ((v != null) && (v.Blob != null))
v.Values = Newtonsoft.Json.JsonConvert.DeserializeObject<List<InputField>>(v.Blob);
}
//Task task = Task.Run(async () => await this.DomainLogicUnitOfWork.VehicleInfoManager.CreateOrUpdate(Entity, EntityId));
/*
* Here I have to call the this.DomainLogicUnitOfWork.VehicleInfoManager.CreateOrUpdate(string Entity, int EntityId) asynchronously
* but return the data without waiting for the CreateOrUpdate to complete
*/
System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken =>
{
await this.DomainLogicUnitOfWork.VehicleInfoManager.CreateOrUpdate(vehiclesList, Entity, EntityId);
});
return data;
}
catch (Exception ex)
{
LogHandler.LogError(9000, "Error updating input fields", ex);
errors.Add("Error 9000:" + ex.Message);
return Json(new
{
error = ex.Message
});
}
}
And I have CreateOrUpdate method defined as below in VehicleInfoManager class
public async Task CreateOrUpdate(string Entity, int EntityId)
{
//do some stuff
var task = Task.Run(() => Test(Entity, EntityId));
//do other stuff
await task;
//some more stuff
}
And Test method is as follows
private void Test(string Entity, int EntityId)
{
List<VehicleInfo> addList; List<VehicleInfo> updateList;
try
{
this.GetAddAndUpdateList(Entity, EntityId, out addList, out updateList);
if ((addList != null) && (addList.Count > 0))
using (var cont = this.UnitOfWork.Context)
{
foreach (var a in addList)
{
cont.VehicleInfos.Add(a);
}
cont.SaveChanges();
}
if ((updateList != null) && (updateList.Count > 0))
using (var cont = this.UnitOfWork.Context)
{
foreach (var a in updateList)
{
var aa = cont.VehicleInfos?.Where(x => x.VehicleInfoId == a.VehicleInfoId)?.FirstOrDefault();
aa.Address_City = a.Address_City;
aa.Address_Country = a.Address_Country;
aa.Address_StateCode = a.Address_StateCode;
aa.Address_Street1 = a.Address_Street1;
aa.Address_Street2 = a.Address_Street2;
aa.Address_Zip = a.Address_Zip;
aa.ChassisYear = a.ChassisYear;
aa.EngineFamilyName = a.EngineFamilyName;
aa.Entity = a.Entity;
aa.EntityId = a.EntityId;
aa.InputFieldEntity = a.InputFieldEntity;
aa.InputFieldEntityId = a.InputFieldEntityId;
aa.InputFieldGroup = a.InputFieldGroup;
aa.LicensePlate = a.LicensePlate;
aa.Manufacturer = a.Manufacturer;
aa.ModelYear = a.ModelYear;
aa.PurchasedDate = a.PurchasedDate;
aa.RegHoldClearBy = a.RegHoldClearBy;
aa.RegHoldClearDate = a.RegHoldClearDate;
aa.RegHoldComment = a.RegHoldComment;
aa.RegHoldSet = a.RegHoldSet;
aa.RegHoldSetBy = a.RegHoldSetBy;
aa.RegHoldSetDate = a.RegHoldSetDate;
aa.TrailerPlate = a.TrailerPlate;
aa.UpdatedBy = a.UpdatedBy;
aa.UpdatedDate = a.UpdatedDate;
aa.VehicleId = a.VehicleId;
aa.VehicleOperator = a.VehicleOperator;
aa.VehicleOwner = a.VehicleOwner;
aa.VIN = a.VIN;
}
cont.SaveChanges();
}
}
catch (Exception ex)
{
ARB.Logging.LogHandler.LogError(9001, "CreateOrUpdate(string Entity, int EntityId) in class VehicleInfoManager", ex);
throw ex;
}
}
What I want is, I want two things here
the Post method to call or start the CreateOrUpdate method as background call but instead of waiting until the CreateOrUpdate method finishes, it should return the result data to UI and continue the big task CreateOrUpdate in the background.
Is there anyway to start the background method CreateOrUpdate after sometime like (10 mins etc) post method returns to UI, if it can't be done, its OK we don't have to worry but just asking if there is anyway to trigger this from within the same application
When I implemented it in the above way, even after using System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem I am still getting the null http context at the following location
user = System.Web.HttpContext.Current.User.Identity.Name; url = System.Web.HttpContext.Current.Request.Url.ToString();
System.Web.HttpContext.Current is coming out as null.
and the application is breaking,
I chaned my async call to the following to use HostingEnvironment.QueueBackgroundWorkItem, still the same htt current context is coming out as null, any help please
System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken =>
{
await this.DomainLogicUnitOfWork.VehicleInfoManager.CreateOrUpdate(Entity, EntityId);
});
Thank you
System.Web.HttpContext.Current is maintained by the ASP.NET's SynchronizationContext.
When you start a new Task, the code will be executing on another thread pool thread without a SynchronizationContext and the value of System.Web.HttpContext.Current is not safe to use, whatever its value.
When the execution of the action method (Post) ends, the request will end and the HttpContext instance will be invalid, even if you mange to get a reference to it.
Also, there is no guarantee that that code you posted to the thread pool will run to complete, since it's out of ASP.NET control and ASP.NET won't be aware of it if IIS decides, for some reason, to recycle the application pool or the web application.
If you to post background work, use HostingEnvironment.QueueBackgroundWorkItem. Beware if its constraints.
var randnumber = CommonClass.Generate8DigitHBFNumber();
bool CheckCaseRef = CheckCaseRefIdAlreadyExistsInDB(randnumber);
if (CheckCaseRef)
{
randnumber = CommonClass.Generate8DigitHBFNumber();
}
else
{
randnumber = CommonClass.Generate8DigitHBFNumber();
}
//Method to Check the generated random number
bool CheckCaseRefIdAlreadyExistsInDB(string randnumber)
{
Log.Info("CheckCaseRefIdAlreadyExistsInDB started...");
bool checkCaseRef = false;
try
{
var ObjCustomerList = db.tblCustomers.ToList();
if (ObjCustomerList != null)
{
foreach (var customerlst in ObjCustomerList)
{
if (!(string.IsNullOrEmpty(randnumber)))
{
if (customerlst.CaseRef == randnumber)
{
checkCaseRef = true;
break;
}
}
}
}
else
{
return checkCaseRef;
}
}
catch (Exception ex)
{
Log.Error("Error CheckCaseRefIdAlreadyExistsInDB started...", ex);
return false;
}
return checkCaseRef;
}**
You might want to do this:
var randnumber = CommonClass.Generate8DigitHBFNumber();
while (! CheckCaseRefIdAlreadyExistsInDB(randnumber))
{
randnumber = CommonClass.Generate8DigitHBFNumber();
}
bool CheckCaseRefIdAlreadyExistsInDB(string randnumber)
{
return db.tblCustomers.Any(c => c.CaseRef == randnumber ?? "");
}
Checking the regenerated one would be an excellent use for recursion. If you don't know much about recursion, I would highly recommend doing some research on it first though, as it can lead to some really nasty memory issues in your code if used incorrectly.
//Code in main method
string randnumber = CheckRandomNumber();
//Recursive method to call
public string CheckRandomNumber()
{
string numToCheck = CommonClass.Generate8DigitHBFNumber();
if (db.tblCustomers.Any(x => x.CaseRef == numToCheck))
{
//Duplicate was found
CheckRandomNumber();
}
return numToCheck;
}
I have written an app that goes through our own properties and scraps the data. To make sure I don't run through the same URLs, I am using a MySQL database to store the URL, flag it once its processed. All this was being done in a single thread and it's fine if I had only few thousand entries. But I have few hundred thousand entries that I need to parse so I need to make changes in the code (I am newbie in multithreading in general). I found an example and was trying to copy the style but doesn't seem to work. Anyone know what the issue is with the following code?
EDIT: Sorry didn't mean to make people guess the issue but was stupid of me to include the exception. Here is the exception
"System.InValidCastException: 'Specified cast is not valid.'"
When I start the process it collects the URLs from the database and then never hits DoWork method
//This will get the entries from the database
List<Mappings> items = bot.GetUrlsToProcess(100);
if (items != null)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Worker.Done = new Worker.DoneDelegate(WorkerDone);
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token));
}
LaunchTasks();
}
static async void LaunchTasks()
{
// keep checking until we're done
while ((WaitingTasks.Count > 0) || (RunningTasks.Count > 0))
{
// launch tasks when there's room
while ((WaitingTasks.Count > 0) && (RunningTasks.Count < MaxRunningTasks))
{
Task task = WaitingTasks.Dequeue();
lock (RunningTasks) RunningTasks.Add((int)task.AsyncState, task);
task.Start();
}
UpdateConsole();
await Task.Delay(300); // wait before checking again
}
UpdateConsole(); // all done
}
static void UpdateConsole()
{
Console.Write(string.Format("\rwaiting: {0,3:##0} running: {1,3:##0} ", WaitingTasks.Count, RunningTasks.Count));
}
static void WorkerDone(int id)
{
lock (RunningTasks) RunningTasks.Remove(id);
}
public class Worker
{
public delegate void DoneDelegate(int taskId);
public static DoneDelegate Done { private get; set; }
public async void DoWork(object id, string url, CancellationToken token)
{
if (token.IsCancellationRequested) return;
Content obj;
try
{
int tries = 0;
bool IsUrlProcessed = true;
DateTime dtStart = DateTime.Now;
string articleDate = string.Empty;
try
{
ScrapeWeb bot = new ScrapeWeb();
SearchApi searchApi = new SearchApi();
SearchHits searchHits = searchApi.Url(url, 5, 0);
if (searchHits.Hits.Count() == 0)
{
obj = await bot.ReturnArticleObject(url);
if (obj.Code != HttpStatusCode.OK)
{
Console.WriteLine(string.Format("\r Status is {0}", obj.Code));
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.HttpCode = obj.Code;
}
else
{
string title = obj.Title;
string content = obj.Contents;
string description = obj.Description;
Articles article = new Articles();
article.Site = url.GetSite();
article.Content = content;
article.Title = title;
article.Url = url.ToLower();
article.Description = description;
string strThumbNail = HtmlHelper.GetImageUrl(url, obj.RawResponse);
article.Author = HtmlHelper.GetAuthor(url, obj.RawResponse);
if (!string.IsNullOrEmpty(strThumbNail))
{
//This condition needs to be added to remove ?n=<number> from EP thumbnails
if (strThumbNail.Contains("?"))
{
article.ImageUrl = strThumbNail.Substring(0, strThumbNail.IndexOf("?")).Replace("http:", "https:");
}
else
article.ImageUrl = strThumbNail.Replace("http:", "https:");
}
else
{
article.ImageUrl = string.IsNullOrEmpty(strThumbNail) ? article.Url.GetDefaultImageUrls() : strThumbNail.Replace("http:", "https:");
}
articleDate = HtmlHelper.GetPublishDate(url, obj.RawResponse);
if (string.IsNullOrEmpty(articleDate))
article.Pubdate = DateTime.Now;
else
article.Pubdate = DateTime.Parse(articleDate);
var client = new Index(searchApi);
var result = client.Upsert(article);
itemfound.HttpCode = obj.Code;
if (result)
{
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate);
UpdateItem(itemfound);
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
UpdateItem(itemfound, tries, IsUrlProcessed);
}
}
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = true;
itemfound.HttpCode = HttpStatusCode.OK;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
}
catch (Exception e)
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
finally
{
DateTime dtEnd = DateTime.Now;
Console.WriteLine(string.Format("\r Total time taken to process items is {0}", (dtEnd - dtStart).TotalSeconds));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Done((int)id);
}
}
All this code is based from Best multi-thread approach for multiple web requests this link. Can someone tell me how to get this approach running?
I think the problem is in the way you're creating your tasks:
new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token)
This Task constructor overload expected Action<object> delegate. That means id will be typed as object and you need to cast it back to something useful first.
Parameters
action
Type: System.Action<Object>
The delegate that represents the code to execute in the task.
state
Type: System.Object
An object representing data to be used by the action.
cancellationToken
Type: System.Threading.CancellationToken
-The CancellationToken that that the new task will observe.
You decided to cast it to int by calling (int)id, but you're passing item.Url as the object itself. I can't tell you 100% what the type of Url is but I don't expect Url-named property to be of type int.
Based on what #MarcinJuraszek said I just went back to my code and added an int as I couldn't find another way to resolve it. Here is the change I made
int i=0
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((string)id, item.Url, token), item.Url, token));
i++;
}
Let me rephrase.
I have a method that generates strings(paths) after given a start string(path)
IF those paths are for a directory I want to enqueue that in the input of the method.
After processing the path synchronously, I want to get the Data and clone it async into multiple paths of a pipeline, were each path needs to get the datablock. So the Broadcastblock is out of the question (it cant send a blocking signal to the blocks before itself),
The joinblock, joining the results is relatively straight forward.
So to sum up
Is there a Block in Dataflow block, where i can access the inputqueue from the delegate, if when, how?
Is there a construct that acts like the broadcastblock but can block the blocks that came before it?
I tried doing it via almighty google:
class subversion
{
private static string repo;
private static string user;
private static string pw;
private static DateTime start;
private static DateTime end;
private static List<parserObject> output;
public static List<parserObject> svnOutputList
{
get {return output; }
}
private static List<string> extension_whitelist;
public async void run(string link, string i_user, string i_pw, DateTime i_start, DateTime i_end)
{
repo = link;
user = i_user;
pw = i_pw;
start = i_start;
end = i_end;
output = new List<parserObject>();
BufferBlock<string> crawler_que = new BufferBlock<string>();
BufferBlock<svnFile> parser_que = new BufferBlock<svnFile>();
var svn = crawl(crawler_que, parser_que);
var broadcaster = new ActionBlock<svnFile>(async file =>
{//tried to addapt the code from this ensure always send broadcastblock -> see link below
List<Task> todo = new List<Task>();
todo.Add(mLoc);//error cannot convert methodgroup to task
foreach (var task in todo)//error: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement?
{
task.SendAsync(file);//error cannot convert task to targetblock
}
await Task.WhenAll(todo.ToArray());
});
parser_que.LinkTo(broadcaster);
await Task.WhenAll(broadcaster, svn);//error cannot convert actionblock to task
}
private static async Task crawl(BufferBlock<string> in_queue, BufferBlock<svnFile> out_queue)
{
SvnClient client = new SvnClient();
client.Authentication.ForceCredentials(user, pw);
SvnListArgs arg = new SvnListArgs
{
Depth = SvnDepth.Children,
RetrieveEntries = SvnDirEntryItems.AllFieldsV15
};
while (await in_queue.OutputAvailableAsync())
{
string buffer_author = null;
string prev_author = null;
System.Collections.ObjectModel.Collection<SvnListEventArgs> contents;
string link = await in_queue.ReceiveAsync();
if (client.GetList(new Uri(link), arg, out contents))
{
foreach (SvnListEventArgs item in contents)
{
if (item.Entry.NodeKind == SvnNodeKind.Directory)
{
in_queue.Post(item.Path);
}
else if (item.Entry.NodeKind == SvnNodeKind.File)
{
try
{
int length = item.Name.LastIndexOf(".");
if (length <= 0)
{
continue;
}
string ext = item.Name.Substring(length);
if (extension_whitelist.Contains(ext))
{
Uri target = new Uri((repo + link));
SvnRevisionRange range;
SvnBlameArgs args = new SvnBlameArgs
{
Start = start.AddDays(-1),
End = end
};
try
{
svnFile file_instance = new svnFile();
client.Blame(target, args, delegate(object sender3, SvnBlameEventArgs e)
{
if (e.Author != null)
{
buffer_author = e.Author;
prev_author = e.Author;
}
else
{
buffer_author = prev_author;
}
file_instance.lines.Add(new svnLine(buffer_author, e.Line));
});
out_queue.Post(file_instance);
}
catch (Exception a) { Console.WriteLine("exception:" + a.Message);}
}
}
catch (Exception a)
{
}
}
}
}
}
}
private static async Task mLoc(svnFile file)
{
List<parserPart> parts = new List<parserPart>();
int find;
foreach (svnLine line in file.lines)
{
if ((find = parts.FindIndex(x => x.uploader_id == line.author)) > 0)
{
parts[find].count += 1;
}
else
{
parts.Add(new parserPart(line.author));
}
find = 0;
}
parserObject ret = new parserObject(parts, "mLoc");
await output.Add(ret);
return;
}
}
broadcastblock answer: Alternate to Dataflow BroadcastBlock with guaranteed delivery
I really don't know what the problem is. I've an win8.1 App which is calling a WCF Method for getting some Data. When i debug the WCF it returns a Task<List<T>> with List.Count=116 Elements in the List but when the List (Task) "arrives" in my App it always says List.Count=0.
Tested with WCF-Testclient too - result:
And the result i get in my Win8 App:
Call:
private List<Person> getPersonList()
{
IService client = CustomServiceBinding.GetClientForIService();
try
{
if (client != null && ((IClientChannel)client).State == CommunicationState.Opened))
{
var personList = client.GetPersonStateList(terminalName);
personList.Wait(Timeout.Infinite);
if (personList.IsCompleted)
{
if (personList.Result == null || personList.Result.Count <= 0)
{
// i'm ALWAYS landing here because the List has no Elements
// but when the method in the WCF returns the List had 116 Elements
// where do they get lost?
}
else
{
foreach (var item in personList.Result)
{
loginTextbox.Text += "Yeah";
}
}
}
}
}
catch (CommunicationObjectFaultedException cofe)
{
ExceptionHandling(cofe);
if (client != null)
{
((IClientChannel)client).Abort();
}
}
catch (Exception ex)
{
ExceptionHandling(ex);
if (client != null)
{
((IClientChannel)client).Abort();
}
}
finally
{
if (client != null)
{
((IClientChannel)client).Close();
((IClientChannel)client).Dispose();
}
}
}
Method in WCF:
public async Task<List<Person>> GetPersonStateList(string terminal)
{
Task<List<Person>> t = Task.Run(() =>
{
List<Person> personList = new List<Person>();
try
{
//calling another WCF - returns 116 Elements
//validatePerson always returns true (hardcoded for testing)
currentPersonList = ServiceBinding.getCurrentPersonList().GetPersonEnumeration().Where(x => validatePerson(x));
}
catch (Exception ex)
{
currentPersonList = null;
ExceptionContainer myException = new ExceptionContainer("Message: " + ex.Message);
throw new FaultException<ExceptionContainer>(myException);
}
if (currentPersonList != null && currentPersonList.Count() > 0)
{
foreach (var item in currentPersonList)
{
TimeSpan ts;
var dailyTimes = item.GetDailyTimeEnumeration();
foreach (var day in dailyTimes)
{
ts = new TimeSpan(0, 0, (int)day.RawValue);
personList.Add(new Person() { Name = item.firstname + " " + item.lastname, dailyTime = ts });
}
}
}
else
{
// i never get in here
personList = null;
}
// at this point the personList has 116 valid Elements
return personList;
});
// this "t" has a List with 116 Elements at the return point
return await t;
}
What am i missing here? Did i forget something? Do i have to lock something (if yes, WHAT should i lock and where?)?
** EDITED **
Added more code examples in WCF Method and two Screenshots from the results i get in WCF and in Win8 App.
** EDITED **
Now i've changed a few things in coding in the given methods above.
Second one is not returning a Task<List<Person>> but just a List<Person>.
The first Method is shortened and looks like this:
private async void updateUI(object sender, object e)
{
try
{
List<Person> list = new List<Person>();
TM2K_Service client = IAGServiceBinding.GetClientForTM2K();
try
{
if (client != null)
{
string terminalName = getTerminalName().ToLower();
// asynchronous
var personList = await client.GetPersonStateList(terminalName);
if (personList == null || personList.Count <= 0)
{
// BUT I'M STILL STUCK HERE WITH A LIST WITH ZERO ELEMENTS (Count=0)
}
else
{
foreach (var item in personList.Result)
{
loginTextbox.Text += "Yeah";
}
}
}
}
catch (Exception x)
{
ExceptionHandling(x);
}
}
catch (Exception ex)
{
ExceptionHandling(ex);
}
}
I get the same Results when i'm calling the IIS published WCF as when i call the WCF-Testclient var personList Count=0.
** EDIT **
I found out it's a problem with deserializing of collections or generic lists. When you add a servicereference via visual studio (clicking) it sets default collection types for deserialization. I'm working with ChannelFactory so i have to set it as KnownType(typeof)? But i'm fairly new to this niveau of coding in WCF or setting programmatically servicereferences on clientside - how and where do i set these attributes? And i tried the known type IList<> too or an Array or an ObservableCollection. No chance to deserialize received data.
How and which attributes do i have to set for deserialization?