我手头有一个相当复杂的编程问题,所以请耐心等待几分钟。
我决定要在 WPF (C#) 中创建一个媒体播放器,但我遇到了一些麻烦。
我希望我的应用程序是单实例,这样当用户双击服务器文件时,程序只会运行一次并将所有文件排队播放。
我尝试了几种方法,包括 Microsoft 的单实例实现,但似乎没有任何效果,直到我决定创建自己的没有出现)
基本上,我使用命名互斥锁来防止打开多个实例,并强制其他实例将其参数写入文件,之后,创建互斥锁的实例将读取该文件。不用说,就性能而言,这非常非常无效,但无论如何,这是我对 Main() 函数的实现。请注意,这个 Main() 也是从头开始编写的,因为我不太喜欢 VS2010 自动生成的那个。
static void Main(string[] args)
{
string[] arguments = new string[0];
handler g = new handler();
bool createdNew = false;
Mutex lolpaca = new Mutex(true, "lolpacamaximumtrolololololol", out createdNew);
if (createdNew)
{
if (args != null)
{
var MainWindow = new MainWindow();
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
else
{
Array.Resize(ref arguments, 1);
arguments[0] = args[0];
string line;
//nu mai arunca exceptii nenorocitule
while ((line = g.ReadArgs()) != null)
{
int old_size = arguments.Length;
Array.Resize(ref arguments, arguments.Length + 1);
arguments[old_size] = line;
}
var MainWindow = new MainWindow(arguments, arguments.Length);
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
if (File.Exists(path))
{
File.Delete(path);
}
}
else
{
Thread writer = new Thread(new ParameterizedThreadStart(g.WriteArg));
writer.Start(args);
writer.Join();
try
{
g.WriteArg(args);
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
}
我也在使用这个类来尝试在线程之间同步
public class handler
{
static string path = @"D:\playlist.txt";
static FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
string line;
string arg;
bool readerFlag = false;
public string ReadArgs()
{
try
{
lock (fs) // Enter synchronization block
{
if (!readerFlag)
{ // Wait until writer finishes
try
{
// Waits for the Monitor.Pulse in WriteArg
Monitor.Wait(fs);
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
TextReader tr = new StreamReader(fs);
while ((line = tr.ReadLine()) != null)
{
arg = line;
}
tr.Close();
tr.Dispose();
}
/* fs.Close();
fs.Dispose();*/
readerFlag = false;
Monitor.Pulse(fs);
return arg;
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
return null;
}
}
public void WriteArg(object args)
{
lock (fs)
{
try
{
if (readerFlag)
{
try
{
Monitor.Wait(fs); // Wait for the Monitor.Pulse in ReadArgs
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
arg = Convert.ToString(args);
// FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
TextWriter tw = new StreamWriter(fs);
tw.WriteLine(args);
tw.Close();
tw.Dispose();
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
/* fs.Close();
fs.Dispose();*/
readerFlag = true;
Monitor.Pulse(fs);
}
}
现在,基本上,对于每个双击文件,Windows 都会创建一个 Main() 函数实例。第一个实例控制了互斥体并继续做它想做的任何事情。其他实例必须将它们的参数写入文件。
现在,问题是:显然,线程(所有线程)没有正确同步,有时我得到 IO 异常。我不知道这些异常到底是在哪里引发的,因为 try-catch 块似乎什么都不做。事实上,我相信这比 try-catch 的作用要深一些。
那么,当用户双击大量文件时,我如何同步所有产生的线程?这个实现最多可以双击 3 个文件,有时(注意,有时它可以工作,其他时候不能)超过 3 个文件(测试最多 9 个)。到目前为止,我在 Internet 上发现的任何内容都无法说明独立运行的同一应用程序的多个实例。
如果能举个例子就好了:)
谢谢你。