B
B
belk2011-09-25 01:09:23
C++ / C#
belk, 2011-09-25 01:09:23

Accessing a Windows Forms Control from Another Thread (C#)?

I'm trying to write a program whose main code will be executed in another thread and add data to the ListBox as I work.
Log is an object of type ListBox.
Creating a thread:

private void bGo_Click(object sender, EventArgs e)
{
    ...
    Log.Items.Add("Старт");
    Thread t = new Thread(Download);
    t.Start();
    t.Join();
    ...
}

Thread work:
void Download()
{
    for (int i = 0; i <= 2; i ++)
    {
        for (int j = 0; j <= 1000; j += 100)
        {
            Thread.Sleep(100);
            //реальный код слал запросы в сеть, 
            //т.е. большую часть времени простаивал
            WriteToLog("test");
        }
    }
}

Working with ListBox:
void WriteToLog(string message)
{
    if (Log.InvokeRequired)
    {
        Log.BeginInvoke(new Action<string>((s)
            => Log.Items.Add(s)), message);
    }
    else
    {
        Log.Items.Add(message);
    }
}

The result is "Start", followed by a three-second pause and 30 "test", although all this should be displayed as the work progresses. If you replace BeginInvoke with Invoke, the program hangs on this line indefinitely. How to make a normal conclusion?

Answer the question

In order to leave comments, you need to log in

6 answer(s)
V
VenomBlood, 2011-09-25
@belk

Since .net 4.0 is used, it is better to use tasks instead of threads:

Task task = new Task(Download);
task.ContinueWith(CodeAfterJoin);
task.Start();

Only here it is necessary to take into account that the continuation will be launched in its own thread.

V
Vitali Borovik, 2011-09-25
@WAYS

Explanatory description of threads here www.rsdn.ru/article/dotnet/CSThreading1.xml
>If you replace BeginInvoke with Invoke, the program hangs on this line for an indefinite time. How to make a normal conclusion?
Because you are using t.Join();

A
afsherman, 2011-09-26
@afsherman

As mentioned above, nothing will work with Join(), because you are waiting for the thread to complete.
In general, look towards asynchronous programming and the BackgroundWorker class.
msdn.microsoft.com/en-us/library/ms228969.aspx

@
@antoo, 2011-09-25
_

stackoverflow.com/questions/7461239/why-does-form-freeze

D
Desiderata, 2011-09-25
@Desiderata

Try like this:

delegate void WriteToLogDelegate(string message);
void WriteToLog(string message)
{
    if (Log.InvokeRequired)
    {
         var writeToLog = new WriteToLogDelegate(WriteToLog);
         Log.Invoke(writeToLog, message);
    }
    else
    {
        Log.Items.Add(message);
    }
}

V
Vitali Borovik, 2011-09-25
@WAYS

private delegate void UpdateListBox(string test);
static object locker = new object();
private void UpLB(string test)
{
lock (locker)
{
Log.Items.Add(test);
}
}
//После чего вызываете
this.Invoke(new UpdateListBox(this.UpLB),new object[] { m.Message});

Try like this

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question