【发布时间】:2016-07-25 12:33:37
【问题描述】:
每次定时器调用UpdateDocumentsListFromServer UI 冻结 3 秒。如何在.net 3.5下以异步方式更新列表?
视图模型:
public class ShippingDocumentsRegisterViewModel : ViewModelBase
{
ShippingDocumentsModel model = new ShippingDocumentsModel();
DispatcherTimer timer = new DispatcherTimer();
BackgroundWorker BW = new BackgroundWorker();
public ShippingDocumentsRegisterViewModel()
{
timer = new DispatcherTimer();
timer.Tick += new EventHandler(UpdateDocumentsListFromServer);
timer.Interval = new TimeSpan(0, 0, 10);
timer.Start();
this.Columns = model.InitializeColumns();
BW.DoWork += UpdateDocumentsList;
BW.RunWorkerAsync();
}
public void UpdateDocumentsList(object o, EventArgs args)
{
this.ShippingDocuments = model.GetDocuments();
}
public void UpdateDocumentsListFromServer(object o, EventArgs args)
{
// Taking a lot of time. How to do it async?
var tempDocuments = model.GetDocumentsFromServer();
foreach (var item in tempDocuments)
{
this.shippingDocuments.Add(item);
}
//
}
private ObservableCollection<ShippingDocument> shippingDocuments;
public ObservableCollection<ShippingDocument> ShippingDocuments
{
get
{
return shippingDocuments;
}
private set
{
shippingDocuments = value;
RaisePropertyChanged("ShippingDocuments");
}
}
public ObservableCollection<ShippingDocumentColumDescriptor> Columns { get; private set; }
}
GetDocumentsFromServer 看起来像
public ObservableCollection<ShippingDocument> GetDocumentsFromServer()
{
System.Threading.Thread.Sleep(3000);
return new ObservableCollection<ShippingDocument> { new ShippingDocument { Name = "Test" } };
}
【问题讨论】:
-
冻结是因为你有
Sleep(3000)。也许您想设置绑定IsAsync(为此它必须是一个属性)?另一个选项是将GetDocumentsFromServer定义为async并在内部使用异步方法(例如await Task.Delay()或者甚至await Task.Run(() => Thread.Sleep()),如果你愿意的话)。 -
@Sinatr,是的,我知道 Sleep(3000) 会冻结 UI。它模拟长时间运行的工作。在 .net 3.5 中没有任何 async、await 方法。
-
我建议使用Timer 而不是
DispactherTimer。DispactherTimer将访问 UIThread,而Timer使用线程池中的线程。 -
.net 3.5 中已经有其他关于异步的帖子...对于example,我认为这可能是重复的(同时考虑到 OP 没有对不同的答案提供任何具体的反馈:-) )
标签: c# wpf asynchronous .net-3.5