Access UI Control on UI Thread using async & a event

时间:2018-03-22 23:22:25

标签: c# wpf multithreading async-await

I am writing a WPF Form Application, in which i am trying to Loop through a FOLDER and show its files REAL TIME, using Async await approach. Within my Task.Run() method I am Raising my event, which raises fine, however that event code also updates a TEXT BOX, which is on UI Thread, hence i am getting UI Thread Error

'The calling thread cannot access this object because a different thread owns it.'

. Is there any way to change my code so I can update my TextBox?

    private delegate void GetFilesCount(string f);
    private event GetFilesCount onFileCount;


    private void Btn_Compare_Click(object sender, RoutedEventArgs e)
    {
        onFileCount += FileCount;
        CountFilesAsync();
    }


    function async void CountFilesAsync() {
            await Task.Run(()=> {
                System.IO.DirectoryInfo myDir = new System.IO.DirectoryInfo(path);
                foreach (FileInfo item in myDir.GetFiles())
                {
                    onFileCount(item.Name); // This is an EVENT
                } 

            });
}

and my event Handler Code

    private void FileCount(string fileName)
    {
            txtLabel_Log.Text = fileName;   // < -- Calling Method UI Error
    }

2 个答案:

答案 0 :(得分:3)

Not sure if this will help you, but you could trying invoking your applications dispatcher.

private void FileCount(string fileName)
{
        Application.Current.Dispatcher.Invoke(() => {
            txtLabel_Log.Text = fileName;   // < -- Calling Method UI Error
        });
}

答案 1 :(得分:2)

Async in 4.5: Enabling Progress and Cancellation in Async APIs

private void Btn_Compare_Click(object sender, RoutedEventArgs e)
{
    CountFilesAsync(Progress<string>(FileCount));
}

private async void CountFilesAsync(IProgress<string> progress)
{
    await Task.Run(() =>
        {
            System.IO.DirectoryInfo myDir = new System.IO.DirectoryInfo(path);
            foreach (FileInfo item in myDir.GetFiles())
            {
                progress(item.Name); // report progress
            } 
        });
}