![](/img/trans.png)
[英]Breaking on a deadlock between multiple startup projects in Visual Studio
[英]Visual Studio delay between multiple startup projects?
如何在解决方案中的启动项目之间添加一些延迟?
我希望在启动WindowsService 2-3秒后启动Client项目。
为什么我需要这个?
WindowsService运行套接字服务器,客户端运行套接字以连接到服务器。 WindowsService加载速度比客户端慢,当连接到尚未运行的服务器时,这会在客户端导致异常
我可能会在客户端中添加一个重试机制。 这样,它不仅有助于“从Visual Studio启动”的情况 - 如果服务器恰好在真实客户端连接时重新启动,它也会有所帮助。 服务器在更快的机器上的事实并不意味着服务器永远不需要重新启动,是吗?
实际上,您可能希望以这样一种方式添加此重试机制,即使服务器在连接时重新启动,客户端也可以恢复。 当然,这取决于项目的进展情况。
您可以使用Mutex锁定来同步两个启动项目。
计划1(StartUp Project 1):
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
class Program1
{
private static bool isNewMutexCreated = true;
private static Mutex mutex;
static void Main(string[] args)
{
mutex = new Mutex(true, "Global\\ConsoleApplication1", out isNewMutexCreated);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
Console.WriteLine("Application1 executed on " + DateTime.Now.ToString());
Console.ReadKey();
}
static void CurrentDomain_ProcessExit(Object sender, EventArgs e)
{
if (isNewMutexCreated)
{
Console.WriteLine("Mutex Released");
mutex.ReleaseMutex();
}
}
}
}
计划2(StartUp Project 2):
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
class Program2
{
static void Main(string[] args)
{
Mutex mutex = null;
Thread.Sleep(5000);
while (mutex == null)
{
try
{
mutex = Mutex.OpenExisting("Global\\ConsoleApplication1");
}
catch (Exception)
{
Console.WriteLine("Mutex not found on " + DateTime.Now.ToString());
Thread.Sleep(3000);
}
}
Console.WriteLine("Application2 executed on " + DateTime.Now.ToString());
Console.ReadKey();
}
}
}
在多个启动项目的情况下, 它们按照既不同时也不随机指定的顺序加载 。 http://msdn.microsoft.com/en-us/library/09138bex(v=vs.90).aspx
所以,如果你在“窗口服务”之后指定“客户”,那么它可能会很好地锻炼。 如果您不想获得上面建议的编码方式,那么(仅用于测试)您可以在所需的延迟后手动将“客户端”过程附加到您的解决方案中。 http://msdn.microsoft.com/en-us/library/c6wf8e4z(v=vs.100).aspx
另一个更简单的测试选项是,如果调试器是这样附加的话,只是延迟客户端:
if (System.Diagnostics.Debugger.IsAttached)
{
System.Threading.Thread.Sleep(2000);
}
如果您愿意,可以将其包装在#if DEBUG
块中。 无论如何,我认为这应该是最少的工作量:)
如果客户需要在之后启动,则需要调整列表,就像之前开始的那样!
我还会在加载应用程序时编写一个“/ wait”,如果它找到该标志,等待它也可能在使用中有用。
您可以将服务器项目设置为单个启动项目,并使用此宏以延迟启动服务器和客户端:
Sub DebugServerAndClientWithDelay()
DTE.Debugger.Go(False)
System.Threading.Thread.Sleep(2000)
DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
DTE.ActiveWindow.Object.GetItem("SolutionName\ClientProjectName").Select(vsUISelectionType.vsUISelectionTypeSelect)
DTE.ExecuteCommand("ClassViewContextMenus.ClassViewProject.Debug.Startnewinstance")
End Sub
您可以向工具栏添加按钮或使用快捷键来运行此宏。
为什么不直接将参数传递给设置延迟的客户端应用程序?
static void main(string[] args)
{
// Sleep some time
int delay;
if (args.Length > 0 && int.TryParse(args, out delay))
{
Thread.Sleep(delay);
}
// Initialize client
}
现在,您可以将延迟(以毫秒为单位)添加到项目启动的命令行参数中。
我也同意,如果可能的话,最好从结构上解决你的问题,所以你的客户端和服务器何时启动并不重要。
只需添加一个过程来检查套接字是否打开。 如果套接字已打开,请继续执行代码并尝试再次检查套接字是否未打开。 这样即使您稍后启动Windows服务也没有问题。
对于我目前正在研究的n层应用程序,我结合了Romil建议的Mutex方法(稍微不同的代码但原理相同)并将其封装在应用了[条件(“DEBUG”)]属性的方法中(因此它得到了)在发布模式中被剥离)。 我们还使用if(System.Diagnostics.Debugger.IsAttached){...}包围互斥逻辑,因为QA构建使用调试模式。
我们最初只使用了Thread.Sleep,其等待时间适用于大多数开发人员的机器,但我们遇到了问题因为开发人员的计算机速度不同而且随着我们向服务器引导程序添加越来越多,我们不得不继续增加等待期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.