C#WPF - 如何在线程中将数据加载到datagrid

时间:2017-09-29 07:27:25

标签: c# wpf multithreading datagrid

我有一个问题,应用程序冻结几秒钟。 我从XML文件加载数据并反序列化为MyList。

public List<My20FieldsDataRecord> MyList;


...



   void ShowDataInThread()
    {
        MyGrid.DataContext = MyList;
    }

    public void ShowDane(bool inThread)
    {

        if (inThread)
        {
            Thread thr = new Thread(ShowDataInThread);
            thr.Start();
        }
        else
        {
            ShowDataInThread();
        }
    }

如果inThread = false一切正常,但应用程序没有响应2-3秒。 当inThread = true应用程序崩溃时。

我想在线程中执行此操作,但我无法从互联网上的示例中了解它是如何工作的。我将非常感谢你的帮助,因为我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

这是我发现在不阻止UI的情况下在后台加载数据网格的数据的一种方法。

首先,创建一个锁对象,并启用集合同步,然后使用Task.Run()在后台线程上实际加载数据:

    private readonly object _myDataLock = new object();

    private FastObservableCollection<My20FieldsDataRecord> MyList = new FastObservableCollection<My20FieldsDataRecord>();
    private CollectionViewSource MyListCollectionView = new CollectionViewSource();

    public MyViewModelConstructor() : base()
    {
        // Other ctor code 
        // ...
        // assign the data source of the collection views
        MyListCollectionView.Source = MyList;               

        // Setup synchronization
        BindingOperations.EnableCollectionSynchronization(MyList, _myDataLock);
    }

    private async void LoadMyList()
    {
                // load the list
                await Task.Run(async () =>
                    {
                        MyList.ReplaceAll(await MyRepository.LoadMyList());
                    }
                );      
    }

然后在您的存储库中,您可以编写:

    public virtual async Task<IList<My20FieldsDataRecord>> LoadMyList()
    {
        var results = await this.DataContext.TwentyFieldDataRecords
           .OrderByDescending(x => x.MyDate).ToListAsync().ConfigureAwait(false);

        return results;
    }   

然后,您可以像这样在关联的视图中进行绑定:

<controls:DataGrid Name="MyListDataGrid" Grid.Row="1"
                   ....
                   ItemsSource="{Binding MyListCollectionView.View}" 
                   ... >

有关详细信息,请参阅:

答案 1 :(得分:-1)

由于Microsoft在.NET 4.5中引入了.NET Framework编程的异步/等待方法,因此异步方法的代码很多。

您无法找到任何异步异步,例如类型:

 private async void button1_Click(object sender, EventArgs e)  
{   
     string result = await AnMethodAsync();
     textBox1.Text += result;  
}

private Task<string> AnMethodAsync()
{
   //Do somethine async
}

你认为这样做了,该函数将运行async,不必再担心挂起thead,太强了。

但问题并非如此简单。 现在尝试将以下代码放入AnMethodAsync()函数:

Thread.Sleep(5000);
return Task.FromResult("HoanHT");

运行上面的代码,当你按下button1时,UI会僵持5秒。 到底是什么,我已经正确地应用了异步/等待UI仍然悬挂。 简要看一下问题:在AnMethodAsync函数中不会在另一个线程上创建任何其他任务。结果是asyn离开了,但它仍然在UI线程上运行 - &gt; UI冻结。

然后解决它,有两种方法:

方法1:创建新任务和可执行文件:

return Task.Factory.StartNew(() =>
   {
      Thread.Sleep(5000);
       return "HoanHT";
   });

方法2:使用Task.Delay()而不是Thread.Sleep()

private async Task<string> AnMethodAsync()
{
  await Task.Delay(5000);
  return "HoanHT";
}

这是我通常对异步问题的处理方式,另外还有一种方法是对Task使用ConfigureAwait(),但会导致小问题。