在我的 ViewModel 中使用 Dispatcher 是错误的吗? [英] Is it wrong to use the Dispatcher within my ViewModel?

查看:16
本文介绍了在我的 ViewModel 中使用 Dispatcher 是错误的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将我在 c# winforms 中编写的游戏的聊天解析器转换为 wpf,主要是为了更好地处理 MVVM 和 wpf.这是我如何设置项目的简要说明

I am converting a chat parser for a game i play that i wrote in c# winforms over to wpf, mainly just to get a better handle on MVVM and wpf. Here is a run down of how i have my project set up

查看:现在它只是一个简单的 ListBox,将 ItemSource 绑定到我的 viewmodels 可观察聊天集合

View: For now its just a simple ListBox with ItemSource bound to my viewmodels observable chat collection

型号:我有多个角色可以一次登录,每个角色都有一个聊天类.聊天类启动一个后台工作程序,从游戏中抓取下一行聊天内容,并使用此行触发一个名为 IncomingChat 的事件.

Model: I have multiple characters that can be logged in at one time and each character has a chat class. The chat class starts a background worker that grabs and next line of chat from the game and fires off an event called IncomingChat with this line.

public event Action<Game.ChatLine> IncomingChat;

我正在使用后台工作人员在我的后台工作人员进度事件中触发一个事件,因为当我使用计时器时,我一直遇到线程问题.起初,我通过将我的 Timer 更改为 DispatchTimer 来纠正此问题,但在我的模型中使用 DispatchTimer 对我来说似乎不合适.

I'm using a background worker to fire an event in my backgroundworkers progresschaged event because when i was using a timer i kept getting a threading issue. At first i corrected this by changing my Timer to a DispatchTimer, but this didn't seem right to me to have a DispatchTimer in my model.

视图模型:由于我有多个角色,因此我正在创建多个 ChatViewModel.我将一个字符传递给 ChatViewModels 构造函数并订阅 Chat 事件.我创建了一个 ObservableColleciton 来在收到此事件时保留我的聊天行.现在,当我尝试将我从聊天事件收到的行添加到我的 observablecollection 时,我在我的 viewModel 上收到了一个线程问题.

ViewModel: Since i have multiple characters i am creating multiple ChatViewModels. I pass a character into the ChatViewModels constructor and subscribe to the Chat event. I create a ObservableColleciton to hold my chat lines when this event is received. Now I'm receiving a threading issue on my viewModel when trying to add the line i receive from my chat event to my observablecollection.

我通过使我的视图模型传入聊天事件处理程序看起来像这样来解决这个问题

I got around this by making my viewmodels incoming chat event handler look like so

public ObservableCollection<Game.ChatLine) Chat {get; private set;}

void Chat_Incoming(Game.ChatLine line)
{
  App.Current.Dispatcher.Invoke(new Action(delegate
  {
    Chat.Add(line)
  }), null);
}

不过我觉得这不太对.虽然它有效,但像这样在我的视图模型中使用 Dispatcher 对我来说似乎不合适.

This doesn't feel right to me though. Although it works, using Dispatcher in my viewmodel like this seems out of place to me.

推荐答案

虽然它有效,但像这样在我的视图模型中使用 Dispatcher 对我来说似乎不合适.

Although it works, using Dispatcher in my viewmodel like this seems out of place to me.

这并非完全不合理的方法,而是许多人采用的方法.就个人而言,如果您使用的是 WPF(或 Silverlight 5),并且可以访问 TPL,我更喜欢使用 TPL 来处理此问题.

This isn't a completely unreasonable approach, and is the approach that many people take. Personally, if you're using WPF (or Silverlight 5), and have access to the TPL, I prefer to use the TPL to handle this.

假设您的 ViewModel 是在 UI 线程上构建的(即:通过 View,或响应与 View 相关的事件),IMO 几乎总是这种情况,您可以将其添加到您的构造函数中:

Assuming your ViewModel is constructed on the UI thread (ie: by the View, or in response to a View related event), which is the case nearly always IMO, you can add this to your constructor:

// Add to class:
TaskFactory uiFactory;

public MyViewModel()
{
    // Construct a TaskFactory that uses the UI thread's context
    uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
}

然后,当你得到你的事件时,你可以用它来编组它:

Then, when you get your event, you can use this to marshal it:

void Chat_Incoming(Game.ChatLine line)
{
    uiFactory.StartNew( () => Chat.Add(line) );
}

请注意,这与您的原始略有不同,因为它不再阻塞(这更像是使用 BeginInvoke 而不是 Invoke).如果您需要在 UI 完成消息处理之前阻止它,您可以使用:

Note that this is slightly different than your original, since it's no longer blocking (this is more like using BeginInvoke instead of Invoke). If you need this to block until the UI finishes processing the message, you can use:

void Chat_Incoming(Game.ChatLine line)
{
    uiFactory.StartNew( () => Chat.Add(line) ).Wait();
}

这篇关于在我的 ViewModel 中使用 Dispatcher 是错误的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆