C # Causing Causes Job never finishes

This is my code:

public void ReadCodes(){
        Task compute = Task.Run(() =>
        {
             //foo code
             foreach (var line in lines)
             {
                 //some other codes
                 SetText("doing something");
             }
        });
        compute.Wait();
        //some other foo
}
private void SetText(string text)
{
        if (this.lblUsedFiles.InvokeRequired)
        {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
        }
        else
        {
                this.lblUsedFiles.Text = text;
        }
}

      

When I remove the SetText("doing something")

call function ReadCodes()

works, otherwise it hangs. What's wrong with my code? I want to update the interface inside Task.Run()

.

+3


source to share


1 answer


Your method ReadCodes

(which is supposedly executing on the UI thread) spawns a new task and blocks it until the end - the UI thread might not do anything until it finishes.

However, your task (which is running on the thread pool) calls Invoke

to start the operation on the UI thread, and also blocks until that completes. Since both operations are blocked waiting for each other, neither of them can continue, resulting in a deadlock.

To fix the problem, the simplest solution is usually to replace yours Invoke

with BeginInvoke

, allowing your task to continue (and complete) without waiting for the UI to refresh. After the task completes, the UI thread is released and handles the pending UI update.



Edit . In response to a question to be updated to include a loop: I would suggest using the asynchronous pattern (introduced in C # 5). This will completely remove blocking UI threads and allow you to perform UI updates as soon as each row has been processed.

public async Task ReadCodes()
{
    foreach (var line in lines)
    {
        string text = await Task.Run(() =>
        {
            //foo code
            // return text;
        });

        this.lblUsedFiles.Text = text;
    }
    //some other foo
}

      

Edit 2: I updated my code based on Peter Duniho's comment . Since it is ReadCodes

supposedly called on the UI thread, you can update the UI directly inside it (unnecessarily Invoke

) while waiting for each task. My guess is that the background processing done in //some other codes

can be integrated into subsequent iteration //foo code

.

+5


source







All Articles