我确实有以下szenario。我创建了一个遵循MVVM模式的WPF C#项目。此外,我开发了一种用户控件,它是某种图像抽屉。现在我在viewmodel中创建一个Model,并将其与usercontrol共享为依赖属性。这是这样做的:
用户控制:
public DXModel Model
{
get { return (DXModel)GetValue(ModelProperty); }
set { SetValue(ModelProperty, value); }
}
public static readonly DependencyProperty ModelProperty =
DependencyProperty.Register("Model", typeof(DXModel), typeof(DXControl),
new PropertyMetadata(null, OnChanged));
static void OnChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
(sender as DXControl).OnChanged();
}
void OnChanged()
{
if (Model != null)
Model.PropertyChanged += new PropertyChangedEventHandler(Model_Changed); // comes from the ui thread...comes only when init model...ok
textTitle.Text = Model.Title;
internalModel = (DXModel)Model;
}
void Model_Changed(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (!receiveTimer.Enabled)
{
receiveTimer.Interval = receiveDelay;
receiveTimer.Start();
refreshTimer.Start();
}
}
因此,当在viewmodel中更改Model时,我也会获得该事件,然后执行绘图。基本上我有一个点列表,我在视图模型中每秒几次完全覆盖:
视图模型:
dxModel1.Series[0].Points = list1;
在用户控件中,每秒重绘几次点数。要做到这一点,我必须首先迭代这些要点:
用户控制:
int length = internalModel.Series[i].Points.Count-1;
float lastX = internalModel.Series[i].Points[0].X;
for (int j = 0; j <= length; j++)
{
float x = ((float)targetImage.Width - 0) / (internalModel.Axes[0].Max - internalModel.Axes[0].Min) * (internalModel.Series[i].Points[j].X- lastX - internalModel.Axes[0].Min);
float y = (0 - (float)targetImage.Height) / (internalModel.Axes[1].Max - internalModel.Axes[1].Min) * (internalModel.Series[i].Points[j].Y - internalModel.Axes[1].Min) + (float)targetImage.Height;
tmpPoints.Add(new SharpDX.Vector2(x, y));
}
重要的是,在视图模型中的工作线程中更改了模型。用户控件生活在ui线程中。我遇到的问题是,通过这些点的迭代不时给我一个例外。我想,这是因为在遍历各点的同时,这些点被覆盖在工作线程中。
我试图锁定usercontrol中的internalModel和viewmodel中的dxModel1,但这对我没有帮助。
我的方法是正确的,为什么它会失败,如果是这样,我怎么能克服这个问题呢?
答案 0 :(得分:0)
我不确定我是否完全理解您的问题,因为没有告诉我们Exception
详细信息,但是如果您只是想确保您的代码在UI上运行线程,你可以做这样的事情:
RunOnUiThread((Action)delegate()
{
int length = internalModel.Series[i].Points.Count-1;
float lastX = internalModel.Series[i].Points[0].X;
for (int j = 0; j <= length; j++)
{
float x = ((float)targetImage.Width - 0) / (internalModel.Axes[0].Max - internalModel.Axes[0].Min) * (internalModel.Series[i].Points[j].X- lastX - internalModel.Axes[0].Min);
float y = (0 - (float)targetImage.Height) / (internalModel.Axes[1].Max - internalModel.Axes[1].Min) * (internalModel.Series[i].Points[j].Y - internalModel.Axes[1].Min) + (float)targetImage.Height;
tmpPoints.Add(new SharpDX.Vector2(x, y));
}
});
...
public object RunOnUiThread(Delegate method)
{
return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}
答案 1 :(得分:0)
如果您正在使用.net4.5,我认为在您的方法中使用async-await应该可以解决这个问题。我遇到的一些链接:http://www.i-programmer.info/programming/c/1514-async-await-and-the-ui-problem.html