This is a migrated thread and some comments may be shown as answers.

Problems with multi threaded Windows Forms Application

2 Answers 106 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Justin Woolich
Top achievements
Rank 1
Justin Woolich asked on 30 Dec 2009, 02:34 AM
Hi,

I am having problems with a multi threaded windows forms application and using Open Access to inertact with the database.

I have set up a demo app to demonstrate the problem (see code below), although the demo app does not represent a business problem it does expose the problem i am having when calling the scope from different threads.

I have a class library with one class called Class1, with a single DateTime property TestDate that has been set up to persist the data to a database.

i have another project with a windows forms application where i have set up 3 buttons, button1 populates the database with some data, button2 retreives the data from the database by calling the GetCount method in a single thread, button3 uses the ThreadPool to call GetCount on different threads multiple times and this is where i am having problems. I get various errors like object not set to an instance of an object or Error executing query... SqlConnection does not support parallel transactions etc. Do i need to syncronize calls (with a lock or similar) to the scope so only one thread is accessing the scope at any one time? or can i somehow allow the threads to use their own scopes independant from the other treads???

Thanks

~~~~~~~~~~~~~~~~
Class Library Code
~~~~~~~~~~~~~~~~

    [Telerik.OpenAccess.Persistent()]
    public class Class1
    {
        private DateTime _testDate;

        public DateTime TestDate
        {
            get
            {
                return _testDate;
            }
            set
            {
                _testDate = value;
            }
        }
    }

~~~~~~~~~~~~~~~~
Windows Forms Application Code
~~~~~~~~~~~~~~~~

    public partial class Form1 : Form
    {
        private IObjectScope _scope = ObjectScopeProvider1.GetNewObjectScope();
       
        private delegate void UpdateLabel(string text);
        private UpdateLabel updateLabel;

        public Form1()
        {
            InitializeComponent();

            updateLabel = new UpdateLabel(OnUpdateLabel);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            for (int count = 0; count < 10; count++)
            {
                _scope.Transaction.Begin();
                Class1 class1 = new Class1();
                class1.TestDate = DateTime.Now;
                _scope.Add(class1);
                _scope.Transaction.Commit();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            GetCount(new object());
        }

        private void button3_Click(object sender, EventArgs e)
        {
            for (int count = 0; count < 100; count++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(GetCount));
            }
        }

        private void GetCount(object obj)
        {
            try
            {
                List<Class1> classList = null;

                lock (_scope)
                {
                    var classes = from class1 in _scope.Extent<Class1>()
                                  select class1;

                    classList = classes.ToList();
                }

                int count = 0;

                foreach (Class1 class1 in classList)
                {
                    DateTime classDate = class1.TestDate;
                    count++;
                }

                this.Invoke(updateLabel, new object[] { count.ToString() });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void OnUpdateLabel(string text)
        {
            label1.Text = text;
        }  
    }

2 Answers, 1 is accepted

Sort by
0
Accepted
Thomas
Telerik team
answered on 30 Dec 2009, 04:43 PM
Hello Justin Woolich,

 multithreaded access to one scope is not our preferred style, but can nevertheless be used. All you need to do is to specify the <option.Multithreaded>True</option.Multithreaded> in your backend configuration. This will synchronize all access to the runtime.

Happy new year!

Kind regards,
Thomas
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Justin Woolich
Top achievements
Rank 1
answered on 30 Dec 2009, 07:44 PM
Hi Thomas,

Thanks for you answer, i also found this article which uses thread slots which may be even better for my application.

http://www.telerik.com/support/kb/orm/general/best-practices-in-winforms-with-orm.aspx

Cheers

-Justin.
Tags
Development (API, general questions)
Asked by
Justin Woolich
Top achievements
Rank 1
Answers by
Thomas
Telerik team
Justin Woolich
Top achievements
Rank 1
Share this question
or