在多线程应用程序中启动新进程时,我是否有任何问题需要仔细处理?
我在一个简单的项目中试过这个:
static void Main(string[] args)
{
Process.Start(@"D:\System\Desktop\a.txt");
MessageBox.Show("Success");
}
它完美运行。但是当我在我使用多线程的大项目中执行它时,它的线程停止工作(“a.txt”打开但“Success”未显示),而我的应用程序(其他线程)运行良好。
这种情况有什么问题?
答案 0 :(得分:2)
如果您有一个Windows.Forms应用程序并且您尝试从不是主用户界面线程的线程显示消息框,则消息框的行为是未定义的。意思是,它可能显示也可能不显示,不一致或其他一些问题。
例如,从BackgroundWorker的DoWork事件中显示消息框可能有效,也可能无效。在一种情况下,无论点击了什么按钮,消息框结果总是被取消。
因此,如果您仅使用消息框进行调试,请使用其他技术。如果必须显示消息框,请从主用户界面线程调用它。
控制台应用程序通常不应该在显示消息框时出现问题。然而,我遇到了一些情况,我必须在消息框调用之前将线程休眠100ms。
注意,正如TomTom指出的那样,主用户界面线程是应用程序的Windows消息循环。这提醒我,我曾经不得不在控制台应用程序中创建一个表单来创建Windows消息循环,因此我的应用程序可以响应Windows消息。
答案 1 :(得分:2)
这不是答案 - 我无法将所有这些代码放在评论中......
这对我有用。告诉我你的代码与此有何不同:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace Test
{
class Program
{
const string OutputFile = @"E:\Output.txt";
object _lock = new object();
static void Main(string[] args)
{
Program program = new Program();
Thread thread = new Thread(program.ThreadMethod);
thread.Start(@"E:\Test.txt");
thread = new Thread(program.ThreadMethod);
thread.Start(@"E:\DoesntExist.txt");
Console.ReadKey();
}
void ThreadMethod(object filename)
{
String result = RunNormal(filename as string);
lock (_lock)
{
FileInfo fi = new FileInfo(OutputFile);
if (!fi.Exists)
{
try
{
fi.Create().Close();
}
catch (System.Security.SecurityException secEx)
{
Console.WriteLine("An exception has occured: {0}", secEx.Message);
return;
}
}
StreamWriter sw = fi.AppendText();
sw.WriteLine(result);
sw.Close();
}
}
string RunNormal(string fullfilename)
{
try
{
Process.Start(fullfilename);
return fullfilename + "|Success";
}
catch (Exception e)
{
return fullfilename + "|" + e.ToString();
}
}
}
}
Output.txt中的输出是:
E:\DoesntExist.txt|System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(String fileName)
at Test.Program.RunNormal(String fullfilename) in E:\Projekti\VS2010\Test\Test\Program.cs:line 59
E:\Test.txt|Success
您的代码有多大不同?你打电话给其他一些方法吗?你如何处理结果?
答案 2 :(得分:0)
确保Process.Start
有效。在某些情况下,传递文件名不够好。在示例代码中,您必须设置use-shell属性;否则,你必须使用cmd start <filename>
或同等的。
因此,只需启动NotePad.exe以确保Process.Start
有效。如果确实如此,则问题是进程命令和命令行。