简体   繁体   English

Visual Studio在多个启动项目之间延迟?

[英]Visual Studio delay between multiple startup projects?

how to add some delay between startup projects in solution? 如何在解决方案中的启动项目之间添加一些延迟?

在此输入图像描述

I want Client project to be started after 2-3 seconds from starting WindowsService. 我希望在启动WindowsService 2-3秒后启动Client项目。

Why I need this? 为什么我需要这个?

WindowsService runs socket server and Client runs socket to connect to server. WindowsService运行套接字服务器,客户端运行套接字以连接到服务器。 WindowsService loads slowly than Client, and this causes an exception on client side when connecting to server which is not run yet WindowsService加载速度比客户端慢,当连接到尚未运行的服务器时,这会在客户端导致异常

I would probably add a retry mechanism within the client. 我可能会在客户端中添加一个重试机制。 That way not only does it help in the "starting up from Visual Studio" case - it also helps if the server happens to be restarting while the real client connects. 这样,它不仅有助于“从Visual Studio启动”的情况 - 如果服务器恰好在真实客户端连接时重新启动,它也会有所帮助。 The fact that the server is on a faster machine doesn't mean the server will never need to restart, does it? 服务器在更快的机器上的事实并不意味着服务器永远不需要重新启动,是吗?

Indeed, you may well want to add this retry mechanism in such a way that the client can recover even if the server is restarted while it's connected. 实际上,您可能希望以这样一种方式添加此重试机制,即使服务器连接时重新启动客户端也可以恢复。 It depends on what the project is doing, of course. 当然,这取决于项目的进展情况。

You can use Mutex locking to sync the two startup project. 您可以使用Mutex锁定来同步两个启动项目。

Program 1 (StartUp Project 1): 计划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();
            }
        }

    }
}

Program 2 (StartUp Project 2): 计划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();
        }
    }
}

In case of multiple start-up projects, they are loaded in the order they are specified neither simultaneously nor randomly. 在多个启动项目的情况下, 它们按照既不同时也不随机指定的顺序加载 在此输入图像描述 http://msdn.microsoft.com/en-us/library/09138bex(v=vs.90).aspx http://msdn.microsoft.com/en-us/library/09138bex(v=vs.90).aspx

So ,may be if you specify "client" after "window service", then it may workout fine. 所以,如果你在“窗口服务”之后指定“客户”,那么它可能会很好地锻炼。 And if you don't want to got the coded way suggested above, then (for testing only) you can manually attach the "client" process to you solution from a different solution after your desired delay. 如果您不想获得上面建议的编码方式,那么(仅用于测试)您可以在所需的延迟后手动将“客户端”过程附加到您的解决方案中。 http://msdn.microsoft.com/en-us/library/c6wf8e4z(v=vs.100).aspx http://msdn.microsoft.com/en-us/library/c6wf8e4z(v=vs.100).aspx

Another simpler option for testing is to just delay the client if the debugger is attached like this: 另一个更简单的测试选项是,如果调试器是这样附加的话,只是延迟客户端:

if (System.Diagnostics.Debugger.IsAttached)
{
    System.Threading.Thread.Sleep(2000);
}

You might wrap that in an #if DEBUG block if you like. 如果您愿意,可以将其包装在#if DEBUG块中。 Anyway I think this should be the least amount of work :) 无论如何,我认为这应该是最少的工作量:)

If the client needs to be started after, you need to adjust your list, as at the moment its started before! 如果客户需要在之后启动,则需要调整列表,就像之前开始的那样!

I would also code a "/wait" which on loading app if it finds that flag, waits for it maybe useful in use too. 我还会在加载应用程序时编写一个“/ wait”,如果它找到该标志,等待它也可能在使用中有用。

You can set the server project as the single startup project and use this macro to launch the server and the client with a delay: 您可以将服务器项目设置为单个启动项目,并使用此宏以延迟启动服务器和客户端:

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

You can add a button to your toolbar or use a shortcut key to run this macro. 您可以向工具栏添加按钮或使用快捷键来运行此宏。

Why don't you just pass an argument to the client application which sets the delay? 为什么不直接将参数传递给设置延迟的客户端应用程序?

static void main(string[] args)
{
  // Sleep some time
  int delay;
  if (args.Length > 0 && int.TryParse(args, out delay))
  {
    Thread.Sleep(delay);
  }

  // Initialize client
}

Now you can add the delay in milliseconds to the command-line arguments for the project startup. 现在,您可以将延迟(以毫秒为单位)添加到项目启动的命令行参数中。

I also agree that if possible, it's better to solve your problem structurally, so it doesn't matter when your client and server start. 我也同意,如果可能的话,最好从结构上解决你的问题,所以你的客户端和服务器何时启动并不重要。

Just add a procedure to check whether the socket is open or not. 只需添加一个过程来检查套接字是否打开。 If the socket is open continue executing your code and try checking again if the socket is not open. 如果套接字已打开,请继续执行代码并尝试再次检查套接字是否未打开。 This way even if you start the windows service later there will be no problem. 这样即使您稍后启动Windows服务也没有问题。

For the n-tier application I am currently working on, I combined the Mutex method suggested by Romil (slightly different code but same principle) and encapsulated it within a method with a [Conditional("DEBUG")] attribute applied (so it gets stripped out in release mode). 对于我目前正在研究的n层应用程序,我结合了Romil建议的Mutex方法(稍微不同的代码但原理相同)并将其封装在应用了[条件(“DEBUG”)]属性的方法中(因此它得到了)在发布模式中被剥离)。 We also surround the mutex logic with if (System.Diagnostics.Debugger.IsAttached) {...} since QA builds use Debug mode. 我们还使用if(System.Diagnostics.Debugger.IsAttached){...}包围互斥逻辑,因为QA构建使用调试模式。

We originally just used a Thread.Sleep with a wait period that worked for most developers machines, but we ran into problems because devs' computer speeds vary and as we added more and more to the server bootstrapper, we had to keep increasing the wait period. 我们最初只使用了Thread.Sleep,其等待时间适用于大多数开发人员的机器,但我们遇到了问题因为开发人员的计算机速度不同而且随着我们向服务器引导程序添加越来越多,我们不得不继续增加等待期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM