Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • montelof 1:11 pm on January 11, 2013 Permalink | Reply  

    Using Action and Func to execute Asynch Operation in a chain. 

     

    public partial class MainPage : UserControl

    {

        int rand;

        public MainPage()

        {

            InitializeComponent();

            rand = 0;

        }

     

        public Func<Action<intint>, Action<int>> DownloadDataInBackground = (callback) =>

        {

            return (c) =>

            {

                WebClient client = new WebClient();

                Uri uri = new Uri(string.Format(https://www.google.com/search?q={0}”, c));

                client.DownloadStringCompleted += (s, e2) =>

                {

                    callback(c, e2.Result.Length);

                };

                client.DownloadStringAsync(uri);

            };

        };

     

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            int callid = rand++;

            Debug.WriteLine(“Executing CallID #{0}”, callid);

            DownloadDataInBackground((c3, r3) => Debug.WriteLine(“The result for the callid {0} is {1}”, c3, r3))(callid);

        }

    }

     
  • montelof 4:54 pm on September 14, 2011 Permalink | Reply  

    Return values from ThreadPool.QueueUserWorkItem in a chain of 3 threads for Silverlight. 

    Basically what I’d like to demonstrate here is how to chain 3 ThreadPool.QueueUserWorkItem calls where each thread return a value that is required by the following thread in a chain, this is also useful when working with MEF since you are working with only one instance of your module, you need to be careful to not use global variables too much, especially when multithreading, so all the results are being pass as return values.

    This return value should not be global because these calls came from another thread waiting for the chains to complete.

    Here is the code:

    First we need to create the link between the threads:

    public class CalcParams

    {

        public int CallID;

        public ManualResetEvent ManualReset;

        public Action<int,ManualResetEvent,int> CallbackDone;

    }

     

    The main thread for the example creates an array of ManualResetEvents, and then executes all the chains in parallel and wait for them to complete.

    private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)

    {

        ThreadPool.QueueUserWorkItem((obj) =>

        {

            ManualResetEvent[] finishcalc = new ManualResetEvent[] 

            { 

                new ManualResetEvent(false), 

                new ManualResetEvent(false), 

                new ManualResetEvent(false), 

                new ManualResetEvent(false), 

                new ManualResetEvent(false), 

                new ManualResetEvent(false

            };

            DoCalculation(rand.Next(10), rand.Next(10), 1, finishcalc[0]);

            DoCalculation(rand.Next(10), rand.Next(10), 2, finishcalc[1]);

            DoCalculation(rand.Next(10), rand.Next(10), 3, finishcalc[2]);

            DoCalculation(rand.Next(10), rand.Next(10), 4, finishcalc[3]);

            DoCalculation(rand.Next(10), rand.Next(10), 5, finishcalc[4]);

            DoCalculation(rand.Next(10), rand.Next(10), 6, finishcalc[5]);

     

            if (WaitHandle.WaitAll(finishcalc))

            {

                AddTextAsync(“DoCalculation Finish \n”);

            }

        });

    }

     

    DoCalculation contains the 3 level deep calculations where all the threads are connected using the class link to pass the parameters:

    void DoCalculation( int number1,int number2,int callid, ManualResetEvent calcdone)

    {

    //Display the values used by the calculation in the corresponding Call ID

    AddTextAsync(string.Format(“The values for Callid {0} are {1} and {2}\n”,callid , number1,number2));

    ThreadPool.QueueUserWorkItem((obj) =>

    {

        //in this case the calculation is the sum of two numbers, it could be any task like

        //call a webservice for the first thread level it is not required to pass the 

        //parameters as part of the link, as for the following levels.so im using the method 

        //parameters directly

        int result = number1 + number2;

        //after calculation is complete that the obj parameter as cast as the link

        CalcParams localparams = (obj as CalcParams);                

        //here Im using the values passed by the Link class to execute the action in 

        //the chain with the method parameters

        localparams.CallbackDone(result,localparams.ManualReset,localparams.CallID);

    }, new CalcParams()

    {

        //these are the method parameters being pass to the thread through the link class

        ManualReset = calcdone,

        CallID = callid,

        //this is the second level callback 

        CallbackDone = (r, m, i) =>

        {                    

            //in the second level I execute another thread passing again the values using 

            //the link class

            ThreadPool.QueueUserWorkItem((obj) =>

            {

                //this time im calculating the sqrt of the previous result

                int sqrt = r*r;

                CalcParams localparams = (obj as CalcParams);

                //im calling the 3rd level Callback passing the result and the original 

                //parameters as well

                localparams.CallbackDone(sqrt, localparams.ManualReset, localparams.CallID);

            }, new CalcParams()

            {                       

                //these are the values for the 2nd level thread

                ManualReset = m,

                CallID = i,

                CallbackDone = (r2, m2, i2) =>

                {

                    //in the 3rd level callback im calculation the double of the result of 

                    //the previous calculation

                    int doublesqrt = r2 * 2;

                    //im showing the result and the call id to the user

                    AddTextAsync(string.Format(“The result for Callid {1} is {0}\n”, doublesqrt, i2));

                    //set the top level ManualResetEvent

                    m2.Set();

                }

            });

        }

    });        

    }

     

    The same logic can be used to execute n levels of chains of threads by simply copying the last level thread inside the last callback you will be passing the ManualResetEvent to the deepest level to set the main thread when the calculation is done.

    Im pretty sure there is much easier way to do it using RX or any other framework available for the .Net Framework 4.0, but this example is intended to demonstrate how to do it for Silverlight using the ThreadPool and Actions only.

     
    • Yohan Jasdid 7:43 pm on October 5, 2011 Permalink | Reply

      Excelente post mi estimado Montelongo!

      Saludos!

      • montelof 8:00 pm on October 5, 2011 Permalink | Reply

        hey q ha bido, gracias, es algo q aplico en un programa q estoy haciendo, despues encontre otra manera de hacer lo mismo sin tanto thread, esta el segundo ejemplo de la pregunta q puse en StackOverflow http://bit.ly/qZvOjY tambien aprendi a hacer lo mismo usando RX pero era mas lento, el primer ejemplo de la pregutna era el mas lento de todos, me quede con la version q puse como segundo ejemplo… Saludos!

  • montelof 9:34 am on March 16, 2011 Permalink | Reply
    Tags: count, distinct, groupby, lambda, , row_count   

    GroupBy two fields,correlate another entity, Count matching rows, show row_number using Lambda 

    I want to count the Tickets owned by every employee, having two Entities,related by Login_ID, so I have first to get the distinct values from the first list, then count the matching rows of the second list, I also want to assign an image url to each employee so I need a row_count like variable, also the related tickets to each employee must match the Team assigned to the employee so the correlated query must consider two fields:

    int index = 0;

    var workload = grouplist.GroupBy(j => new { j.LOGIN_ID, j.FULL_NAME,j.TEAM_NAME})

                    .Where(k => k.Key.TEAM_NAME == membergroup)

                    .Select(i => new

                    {

                        CoreID = i.Key.LOGIN_ID,

                        TicketCount = tickets

                            .Where(k => k.Assignee_Login_ID == i.Key.LOGIN_ID   &&                      k.Assigned_Group==i.Key.TEAM_NAME)

                            .Count(),

                        Assignee = i.Key.FULL_NAME,

                        url = @"~\images\man_" + (1 + (index++) % 5) + ".png"

                    }).ToList();           

    I choose to use Lambda instead of Linq because of simplicity, Ill post another example using left outer join using Linq in the next one.   

     
  • montelof 8:10 am on March 9, 2011 Permalink | Reply
    Tags: , programing   

    OCIEnvCreate failed with return code -1 but error message text was not available. 

    If anyone is getting this error it could be caused for a setting in the project properties:

    change update Database to False and the error will go away.

     
    • waqar hussain 2:18 am on July 26, 2011 Permalink | Reply

      project manager model property windoq, how can i open window,please help me, i am in graet trouble.

      • montelof 9:38 am on July 26, 2011 Permalink | Reply

        if you are using VS 2008 , just select the project in solution explorer, the properties window will show its properties, there, you can then change the setting for UpdateDatabase from false to True.
        hope this helps.

  • montelof 10:09 pm on February 23, 2011 Permalink | Reply
    Tags: missing lan, source, visual studio, vss   

    Visual SourceSafe missing LAN option 

    One night I was working very happy at 3am from home when my project started to shows VSS error about the database does not exist anymore, I thought is time to go bed I don’t have time for this..Next day I woke up thinking I just had a nightmare about my SourceSafe db was gone…but It wasn’t a dream, the db was actually gone, at least totally inaccessible from VS, I was able to see the files directly on the server but I was unable to see it from VS, I tried reinstall update path VSS nothing works, until I found an option in visual studio (that magically changed itself) that was setting VSS Internet by default, here is the screenshot:

    image

    Just changed it back to Visual Source Safe and everything went back to normal.

     
  • montelof 3:36 pm on September 30, 2010 Permalink | Reply
    Tags: , , development, , , xml   

    Error processing response stream. The XML element contains mixed content. 

    Ok, in my last post I explained how to pass an array of values to the Webget method of an Ado DataService as a primitive value (csv), in this post Im going to show how to retrieve a primitive value from a Webget method avoiding the error message above.

    Lets start with the Dataservice:

    [WebGet] //we are going to return an int

    public IQueryable<int> DWTNewDownTime(int metricArrayID, string metricDate)

    {  //create the command as we used to do in 1.1

        DbCommand cmd = this.CurrentDataSource.Connection.CreateCommand();

        cmd.CommandType = CommandType.StoredProcedure;

        //add the parameters needed for the stored procedure

        EntityParameter MetricArrayID = new EntityParameter("MetricArrayID", DbType.Int16);

        MetricArrayID.Value = metricArrayID;

        cmd.Parameters.Add(MetricArrayID);

        EntityParameter MetricDate = new EntityParameter("MetricDate", DbType.String, 50);

        MetricDate.Value = metricDate;

        cmd.Parameters.Add(MetricDate);      

        //add an output parameter, this parameter should be returned as a SELECT not return from the stored procedure

        EntityParameter Res = new EntityParameter("res", DbType.Int16, 20);

        Res.Direction = ParameterDirection.Output;

        cmd.Parameters.Add(Res);

        //constructs the command text

        cmd.CommandText = string.Format(@"{0}.{1}", this.CurrentDataSource.DefaultContainerName, "DWTGetMetricValuesNewDownTimeActions");

        try

        {//open connection and execute an scalar

            cmd.Connection.Open();

            cmd.ExecuteScalar();

        }

        catch (System.Exception ex)

        {

            throw new System.Exception(ex.InnerException.Message);

        }

        finally

        {   //always close the connection

            cmd.Connection.Close();

        }//return the result output value.

        List<int> _list = new List<int> { Convert.ToInt32(Res.Value) };

        return _list.AsQueryable();

    }

     

    As I mention above the stored procedure should return the output parameter as SELECT.

    now lets see the ModelView:

     

    public void DWTGetMetricValuesNewDownTimeActions(int metricArrayID, string metricDate)

    {   //create a DataserviceQuery as we normally do for other webget methods

        QryInsertMetric = this.context.CreateQuery<int>("DWTNewDownTime")

            .AddQueryOption("MetricArrayID", metricArrayID)

            .AddQueryOption("MetricDate", "’" + metricDate + "’");

        //then create a webclient that will be used to execute the above query

        WebClient wc = new WebClient();

        wc.DownloadStringAsync(QryInsertMetric.RequestUri);

        wc.DownloadStringCompleted += (s, e) =>

        {   //we have to parse the returning XML

            XDocument xdoc = XDocument.Parse(e.Result);

            MetricValueID = Convert.ToInt32(xdoc.Root.Descendants(((XNamespace)@"http://schemas.microsoft.com/ado/2007/08/dataservices&quot;) + "element")

                .Select(xe => xe.Value).ToList().Single());

            //fire the property so you can catch it at your silverlight client

            FirePropertyChanged("MetricValueID");

        };

    }

     

    Finally just catch the property change at your client:

    void Downtimemodel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

    {

        if (e.PropertyName == "MetricValueID")

        {

            Console.WriteLine(Downtimemodel.MetricValueID.ToString());

        }   

    }

    and that’s it, I hope this help someone get home early.

    some help from Invoking a WebGet throws an exception @ msdn

     
  • montelof 3:53 pm on September 9, 2010 Permalink | Reply
    Tags: , ,   

    Only primitive types are supported as parameters 

    This is the error message i got when tried to pass an array or List to an Ado Dataservice. It looks like you can only use int, string etc, when passing parameters to the webget method, this is a limitation on the Dataservice it self, not the Datacontext, you can easily workaround this by passing the comma separated values to the Dataservice then split the values before calling your DataContext.

    To convert from the string array to the comma separated use this on your silverlight code:

    string _csvproducts = string.Join(“,”, productList);


    you webget method on the Dataservice should look like this:

    [WebGet]

    public IQueryable<ModelWorkcenter> FilterByModelList(string models)

    {

    string[] _modelsqry = models.Split(‘,’).Select(sValue => sValue.Trim()).ToArray();

    var result = this.CurrentDataSource.GetModelsByList(_modelsqry);

    return result;

    }

    what im doing is to split again the values and passing them to the Datacontext method GetModelsByList this method is expecting a List<string> parameter. your Context class should look like this:

    public IQueryable<ModelWorkcenter> GetModelsByList(IList<string> modelList)

    {

    var result = (from c in Scope.Extent<ModelWorkcenter>() where modelList.Contains(c.TopMaterial) select c);

    return result;

    }

    This way your Linq to SQL will generate good SQL code using the IN clause something like

    Select Model from ITEM_MASTER where Model in (‘model1’,’model2’,’model3’,’model4’)
    To call the webget method use the CreateQuery method of your proxy class so you can add the parameter using AddQueryOption

    public void CustomFilterModels(string models)

    {

    QryModelWorkcenter = Entities.CreateQuery<ModelWorkcenter>(“FilterByModelList”)

    .AddQueryOption(“models”, “‘” + models + “‘”);

    QryModelWorkcenter.BeginExecute(this.GetModelWorkcenterCallback, this.Entities);

    }

    Also note that I’m adding single quotes to the string, without quotes the url cant be parsed correctly and you will get syntax error. this is the generated Url:

    http://localhost:3122/workcenters_service.svc/FilterByModelList()?models=’PPT2633-ZRIY0Y03,PPT2637-TRIZ0Y03,PPT2637-ZRIY0Y00′

    I have read some post about very complex ways to do the same thing, others build the e-sql from scratch, I liked like this because seems more clear and easy to understand.

    Please leave your comments.

    source:http://stackoverflow.com

     
  • montelof 11:32 am on December 17, 2009 Permalink | Reply
    Tags: 3dmark vantage, ati 3870, crossfire,   

    13940 3DMark2006!!! 

    Por fin pase los 10K aqui pongo la configuracion q use, y todo gracias al tutorial de optimizacion publicado anteriormente..

     
  • montelof 11:09 pm on November 10, 2009 Permalink | Reply  

    Por fin CPU al 100% y a 70 grados!!! 

    Monitor

     
  • montelof 2:55 pm on October 17, 2009 Permalink | Reply
    Tags: benchmark, cpu, fluctuations, java, monitor, , power, problem, temperature   

    Esta tu CPU al 70%? 

    Desde q compre esta laptop me visto q en algunos juegos q requieren mucho uso del procesador, los FPS variaban entre 60 y 20 fps, siempre pense q era problema por incompatibilidad de los drivers de la tarjeta de video, hoy, quise hacer una prueba de Benchmark, q tambien hice en la pc del trabajo (770 fps) para ver como salia, me di cuenta q los FPS variaban entre 2300 a 1000…

    image

    Buscando sobre el problema encontre q podria ser por el calentamiento del procesador, asi q baje CPUID Hardware Monitor, el cual comenzo a mostrar variaciones en la temperatura de 70 a 100 grados centigrados cada 5 segundos, y al mismo tiempo q bajaba a 70 grados, era cuando los FPS bajaban tambien a 1600…

    image

    La unica solucion q encontre fue bajar el uso del CPU al 70% de esa manera ya no fluctua mas, pero claro, el uso del procesador se mantiene bajo, pero la temperatura estable en 80 Grados C.

    image

    Verifiquen q no tienen el mismo problema siguiendo los mismos pasos, tal vez podrían salvar su CPU de q se queme, antes q sea muy tarde.

    Edit: Despues de darle una limpiada a los disipadores de mi laptop, logre subir al 85% de uso de CPU sin problemas, y probando el 3DMark2006 obtuve 8914 puntos en lugar de los 8500 q siempre habia sacado y 3500 en el plasma (foto).

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Follow

Get every new post delivered to your Inbox.