Share via


How to solve System.InvalidOperationException on a stream project?

Question

Thursday, September 18, 2014 5:54 PM

hi

i write a program to open files using file stream.but when i open a file i face with this error:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'tbResults' accessed from a thread other than the thread it was created on.

here is my code:

        private void btnSync_Click(object sender, EventArgs e)
        {
            Thread thdSyncRead = new Thread(new ThreadStart(syncRead));
            thdSyncRead.SetApartmentState(ApartmentState.STA);
            thdSyncRead.Start();
        }

        public void syncRead()
        {
            openFileDialog.ShowDialog();
            FileStream fs;
            try
            {
                fs = new FileStream(openFileDialog.FileName, FileMode.OpenOrCreate);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            fs.Seek(0, SeekOrigin.Begin);
            fileContents = new byte[fs.Length];
            fs.Read(fileContents, 0, (int)fs.Length);
            tbResults.Text = Encoding.UTF8.GetString(fileContents);
            fs.Close();
        }

this exception happened on this line: 

tbResults.Text = Encoding.UTF8.GetString(fileContents);

thanks foe your help.

All replies (5)

Friday, September 19, 2014 1:53 PM âś…Answered

thanks

but i'm beginner.

can you explain it,please?

UI, User Interface, controls on WinForms are special objects that require that you follow a couple of simple rules.  The biggest rule is that you can only modify UI Controls on the thread that initially declared and modified them.  Fortunately, there are a couple of tools built right into every control that are available to make that easy to accomplish.  Second, you can reference just a couple of class members of UI controls from another thread, but you cannot reference anything else.

Control.InvokeRequired 

Control.Invoke 

InvokeRequired is such a property that helps you determine whether or not your code that wants to modify a control is executing on the proper thread.  Invoke is a method that allows you to pass a delegate to the control so that it can execute the delegate's target method on the proper thread for the UI Control.  Code examples are posted at the links  Hope this helps.

Rudy   =8^D

[EDIT]  If you need help understanding delegates and a more in depth explanation of this issue take a look at this old thread....

http://social.msdn.microsoft.com/Forums/vstudio/en-US/aee6e3bb-923c-4778-98bf-1c86354e80df/why-i-cant-understand-delegates-in-this-example?forum=csharpgeneral

Mark the best replies as answers. "Fooling computers since 1971."

http://thesharpercoder.com/


Thursday, September 18, 2014 6:13 PM

All UI Controls must be referenced only from the thread where they were declared and initialized.

Mark the best replies as answers. "Fooling computers since 1971."

http://thesharpercoder.com/


Friday, September 19, 2014 11:37 AM

thanks

but i'm beginner.

can you explain it,please?


Friday, September 19, 2014 11:44 AM | 1 vote

The line,

tbResults.Text = Encoding.UTF8.GetString(fileContents);

is not allowed on any other thread than the thread which created tbResults object.

In other words, as Rudedog2 said UI controls can only be updated on the thread where they were created.

To Find out whether you're on correct thread or not, you can use tbResults.InvokeRequired property.

If the return value is true then you'll need to call another method using tbResults.Invoke() that'll ensure that the method gets called on correct thread. In this method you'll be able to update tbResults object.

Hope it helps

Do not Forget to Vote as Answer/Helpful, please. It encourages us to help you...


Friday, September 19, 2014 12:03 PM | 1 vote

Replace line which produce exception with:

tbResults.Invoke(new MethodInvoker(() => tbResults.Text = Encoding.UTF8.GetString(fileContents)))

This will make sure that method is invoked on UI thread - the thread on which texBox was created.