简体   繁体   English

Dispatcher:中止调度程序操作

[英]Dispatcher: abort dispatcher operation

I want adding items to DataGrid in thread. 我想在线程中向DataGrid添加项目。

I have view model for my user control: 我有我的用户控件的视图模型:

public class Contact
{
    public string Name { get; set; }
    public string Phone { get; set; }
}

public class ContactGridViewModel
{
    public ContactGridViewModel()
    {
        Items = new ObservableCollection<Contact>();
    }

    public ObservableCollection<Contact> Items { get; private set; }

    public Dispatcher Dispatcher
    {
        get { return Dispatcher.CurrentDispatcher); }
    }
    private DispatcherOperation LastOperation { get; set; }

    public void Update(IEnumerable<Contact> contacts)
    {
        if (LastOperation != null) LastOperation.Abort();

        Items.Clear();
        foreach (var item in contacts)
            LastOperation = Dispatcher.BeginInvoke(
                    DispatcherPriority.Background,
                    new ParameterizedThreadStart(o => Items.Add(o))),
                    item);
    }
}

There is the markup example: 有标记示例:

<!--DataContext="{Binding ContactGridViewModel}-->

<DataGrid ItemsSource="{Binding Items, Mode=OneWay}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" />
    <DataGridTextColumn Header="Phone" Binding="{Binding Path=Phone}" />
  </DataGrid.Columns>
</DataGrid>

After Update method is executed second time, and if first collection is not completely added, DataGrid will contains part of first collection and full second collection. 在第二次执行Update方法之后,如果没有完全添加第一个集合,DataGrid将包含第一个集合和完整第二个集合的一部分。

// contactList1 and contactList2 are IEnumerable<Contact> objects
Model.Update(contactList1);
Model.Update(contactList2);

I try to abort DispatcherOperation, but it's not stop adding contacts into Items property. 我尝试中止DispatcherOperation,但它不会停止向Items属性添加联系人。

Could you tell me the correct method of adding objects to DataGrid ItemsSource? 你能告诉我向DataGrid ItemsSource添加对象的正确方法吗?

You should collect all DispatcherOpretations in list and then abort them all. 您应该在列表中收集所有DispatcherOpretations,然后将它们全部中止。

public class ContactGridViewModel
{
    public ContactGridViewModel()
    {
        Items = new ObservableCollection<Contact>();
        LastOperations = new List<DispatcherOperation>();
    }

    public ObservableCollection<Contact> Items { get; private set; }
    private ICollection<DispatcherOperation> LastOperations { get; set; }

    public Dispatcher Dispatcher
    {
        get { return Dispatcher.CurrentDispatcher); }
    }

    private void StopUpdating()
    {
        foreach (var operation in LastOperations)
        {
            operation.Abort();
        }
        LastOperations.Clear();
    }

    public void Update(IEnumerable<Contact> contacts)
    {
        StopUpdating();

        Items.Clear();
        foreach (var item in contacts)
            LastOperations.Add(Dispatcher.BeginInvoke(
                    DispatcherPriority.Background,
                    new ParameterizedThreadStart(o => Items.Add(item))),
                    item));
    }
}

In your Update(contactList1) method you start a Dispatcher.BeginInvoke() for every item in contactList1, but if you enter Update(contactList2) you abort only once the LastOperation, which is not the complete foreach but an single Items.Add() . Update(contactList1)方法中,为contactList1中的每个项启动Dispatcher.BeginInvoke() ,但是如果输入Update(contactList2) ,则只会中止LastOperation,这不是完整的foreach而是单个Items.Add()

Try something like this (not tested): 尝试这样的事情(未经测试):

public void Update(IEnumerable<Contact> contacts)
{
    if (LastOperation != null) LastOperation.Abort();

    Items.Clear();
    LastOperation = Dispatcher.BeginInvoke(
        DispatcherPriority.Background,
        new ParameterizedThreadStart(o => { foreach (var item in o) Items.Add(item); }),
        contacts);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM