现在我有以下内容:
private void DoSomethingAsync() {
ProgressBarVisibility = Visibility.Visible;
Task.Factory.StartNew(() => { PerformCDDetection(); }).ContinueWith(t => { ProgressBarVisibility = Visibility.Collapsed; });
}
public ICommand ImportFilePathCommand
{
get
{
return new RelayCommand(() => { DoSomethingAsync(); });
}
}
private void PerformCDDetection()
{
//Gets all the drives
DriveInfo[] allDrives = DriveInfo.GetDrives();
//checks if any CD-Rom exists in the drives
var cdRomExists = allDrives.Any(x => x.DriveType == DriveType.CDRom);
// Get all the cd roms
var cdRoms = allDrives.Where(x => x.DriveType == DriveType.CDRom && allDrives.Any(y => y.IsReady));
if (cdRomExists.Equals(true))
{
// Loop through the cd roms collection
foreach(var cdRom in cdRoms)
{
Console.WriteLine("Drive {0}", cdRom.Name);
Console.WriteLine(" File type: {0}", cdRom.DriveType);
if (cdRom.IsReady == true)
{
if (cdRom.DriveType == DriveType.CDRom)
{
DirectoryInfo di = new DirectoryInfo(cdRom.RootDirectory.Name);
var file = di.GetFiles("*.xml", SearchOption.AllDirectories).FirstOrDefault();
if (file == null)
{
Console.WriteLine("failed to find file");
}
else
{
foreach (FileInfo info in di.GetFiles("*.xml", SearchOption.AllDirectories))
{
Debug.Print(info.FullName);
break; // only looking for the first one
}
break;
}
}
}
else if (cdRom.IsReady == false)
{
Console.WriteLine("Cd-ROM is not ready");
break;
}
}
}
else
{
Console.WriteLine("CD ROM is not detected");
}
}
Console.WriteLine语句应该是dialogWindows / Message Box,弹出警告用户列出的条件。
我删除了消息并用Console.WriteLine语句替换它,因为我无法在后台任务上运行messagebox.show()(它应该是UI线程的一部分而不是后台)。
我想知道因为根据在后台执行的逻辑显示消息,我该如何显示消息框?
在以下示例中,如何在UI线程和后台线程之间来回切换?
编辑:这是我想在UI线程上运行的一段代码:
errorWindow.Message = LanguageResources.Resource.File_Not_Found;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
break;
如果我这样做:
Dispatcher.BeginInvoke(() =>
{
errorWindow.Message = LanguageResources.Resource.File_Not_Found;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
break;
}
);
我收到以下错误消息:
Control cannot leave the body of an anonymous method or lambda expression (for break;)
Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
我使用break来摆脱循环,我应该绕过我的逻辑来避免使用break还是有办法让我仍然可以使用break?
答案 0 :(得分:2)
您可以创建可从应用程序的任何部分访问或调用的可重用MessageService。
这样的事情:
注意:此代码假定在UI线程上创建了MessageService实例。如果您将此实例注入BootStrapper内的容器,通常就是这种情况。否则,即使您从任何.xaml.cs代码中实例化,也可以工作。
/// <summary>
/// Could be injected to your UnityContainer as singleton and then accessed by using Container.Resolve
/// </summary>
public interface IMessageService
{
void ShowDialog(string message, MessageBoxButton messageBoxButton);
}
public class MessageService : IMessageService
{
private readonly Dispatcher _dispatcher;
public MessageService()
{
if(Application.Current!=null){
_dispatcher = Application.Current.Dispatcher;
}
else{
_dispatcher = Dispatcher.CurrentDispatcher;
}
}
public void ShowDialog(string message, MessageBoxButton messageBoxButton)
{
if (_dispatcher.CheckAccess())
{
Show(message, messageBoxButton);
}
else
{
_dispatcher.Invoke(new Action(() => Show(message, messageBoxButton)));
}
}
private static void Show(string message, MessageBoxButton messageBoxButton)
{
MessageBox.Show(Application.Current.MainWindow, message, "TITLE", messageBoxButton);
}
}
编辑:如果不使用任何统一容器,您只需从代码中实例化MessageService即可。喜欢内部&#34; DoSomethingAsync&#34;在你的情况下。
答案 1 :(得分:1)
您应该查看Dispatcher.Invoke和Dispatcher.BeginInvoke方法。
您可以执行以下操作:
Dispatcher.BeginInvoke((Action)(() => MessageBox.Show("some message to display")));
控件不能离开匿名方法或lambda的主体 表达式(用于休息;)
中断需要在Dispatcher调用之外。 你可以这样做:
Dispatcher.BeginInvoke(...);
break;
其他人可以看到:
正如聊天中所讨论的,您需要从UI线程中获取调度程序,然后将其传递给您的任务。
示例:
private void DoSomethingAsync() {
/* here we are on the UI thread */
Dispatcher dispatcher = (Application.Current!=null) ?
Application.Current.Dispatcher :
Dispatcher.CurrentDispatcher;
ProgressBarVisibility = Visibility.Visible;
Task.Factory.StartNew(() => {
/* here we are on the background thread */
PerformCDDetection(dispatcher);
}).ContinueWith(t => { ProgressBarVisibility = Visibility.Collapsed; });
}
你需要对Manish的课程做同样的事情:
private void DoSomethingAsync() {
MessageService messageService = new MessageService();
ProgressBarVisibility = Visibility.Visible;
Task.Factory.StartNew(() => { PerformCDDetection(messageService); }).ContinueWith(t => { ProgressBarVisibility = Visibility.Collapsed; });
}