Jaka jest najlepsza praktyka w przypadku „Kopiuj lokalnie” i z odniesieniami do projektów?


154

Mam duży plik rozwiązania C # (~ 100 projektów) i próbuję poprawić czas kompilacji. Myślę, że „Kopiuj lokalnie” w wielu przypadkach jest dla nas marnotrawstwem, ale zastanawiam się nad najlepszymi praktykami.

W naszym .sln mamy aplikację A zależną od zespołu B, która zależy od zespołu C. W naszym przypadku mamy dziesiątki "B" i garść "C". Ponieważ są one zawarte w .sln, używamy odwołań do projektów. Wszystkie zestawy są obecnie kompilowane w $ (SolutionDir) / Debug (lub Release).

Domyślnie program Visual Studio oznacza te odwołania do projektów jako „Kopiuj lokalne”, co powoduje, że każde „C” jest kopiowane do $ (SolutionDir) / Debug raz na każde „B”, które jest kompilowane. Wydaje się to marnotrawstwem. Co może się nie udać, jeśli wyłączę opcję „Kopiuj lokalnie”? Co robią inne osoby z dużymi systemami?

NASTĘPUJĄCE:

Wiele odpowiedzi sugeruje rozbicie kompilacji na mniejsze pliki .sln ... W powyższym przykładzie najpierw zbudowałbym klasy podstawowe „C”, a następnie większość modułów „B”, a następnie kilka aplikacji, „ ZA". W tym modelu potrzebuję odwołań niezwiązanych z projektem do C z B. Problem, który tam napotykam, polega na tym, że „Debugowanie” lub „Wydanie” jest wypalane w ścieżce podpowiedzi i kończy się budowanie moich kompilacji wydania „B” przeciwko kompilacjom debugowania „C”.

Dla tych z Was, którzy podzielili kompilację na wiele plików .sln, jak poradzicie sobie z tym problemem?


9
Możesz ustawić ścieżkę podpowiedzi w odniesieniu do katalogu debugowania lub wydania, edytując plik projektu bezpośrednio. Użyj $ (Configuration) zamiast Debug lub Release. Np. <HintPath> .. \ output \ $ (Configuration) \ test.dll </HintPath> To jest uciążliwe, gdy masz dużo odniesień (chociaż nie powinno być trudne dla kogoś napisanie dodatku do zarządzaj tym).
ultravelocity

4
Czy opcja „Kopiuj lokalnie” w programie Visual Studio jest taka sama jak <Private>True</Private>w przypadku csproj?
Colonel Panic

Ale dzielenie Up .slnna mniejsze łamie automagii obliczenia współzależności vs dotyczącą <ProjectReference/>s. Sam przeniosłem się z wielu mniejszych .slnna jeden duży, .slntylko dlatego, że VS powoduje w ten sposób mniej problemów… Może więc w dalszej części przyjmuję niekoniecznie najlepsze rozwiązanie pierwotnego pytania? ;-)
binki

Z czystej ciekawości. Po co komplikować sprawy i mieć ponad 100 projektów na pierwszym miejscu? Czy to zły projekt, czy co?
przydatneBee

@ColonelPanic Yes. Przynajmniej to się zmienia na dysku, kiedy zmieniam ten przełącznik w GUI.
Zero3

Odpowiedzi:


85

W poprzednim projekcie pracowałem z jednym dużym rozwiązaniem z odniesieniami do projektu i napotkałem również problem z wydajnością. Rozwiązanie było trojakie:

  1. Zawsze ustawiaj właściwość Copy Local na false i wymuszaj to za pomocą niestandardowego kroku msbuild

  2. Ustaw katalog wyjściowy dla każdego projektu na ten sam katalog (najlepiej względem $ (SolutionDir)

  3. Domyślne cele cs, które są dostarczane z platformą, obliczają zestaw odniesień do skopiowania do katalogu wyjściowego aktualnie budowanego projektu. Ponieważ wymaga to obliczenia domknięcia przechodniego w ramach relacji „Referencje”, może to być BARDZO kosztowne. Moim obejściem tego problemu było ponowne zdefiniowanie GetCopyToOutputDirectoryItemscelu we wspólnym pliku celów (np. Common.targets), Który jest importowany w każdym projekcie po zaimportowaniu pliku Microsoft.CSharp.targets. W rezultacie każdy plik projektu wygląda następująco:

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        ... snip ...
      </ItemGroup>
      <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
      <Import Project="[relative path to Common.targets]" />
      <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
           Other similar extension points exist, see Microsoft.Common.targets.
      <Target Name="BeforeBuild">
      </Target>
      <Target Name="AfterBuild">
      </Target>
      -->
    </Project>

Skróciło to nasz czas kompilacji w danym momencie z kilku godzin (głównie z powodu ograniczeń pamięci) do kilku minut.

Przedefiniowana GetCopyToOutputDirectoryItemsmogą być tworzone poprzez kopiowanie linie 2,438-2,450 oraz 2,474-2,524 od C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targetsdo Common.targets.

Aby uzyskać kompletność, wynikowa definicja celu staje się wtedy:

<!-- This is a modified version of the Microsoft.Common.targets
     version of this target it does not include transitively
     referenced projects. Since this leads to enormous memory
     consumption and is not needed since we use the single
     output directory strategy.
============================================================
                    GetCopyToOutputDirectoryItems

Get all project items that may need to be transferred to the
output directory.
============================================================ -->
<Target
    Name="GetCopyToOutputDirectoryItems"
    Outputs="@(AllItemsFullPathWithTargetPath)"
    DependsOnTargets="AssignTargetPaths;_SplitProjectReferencesByFileExistence">

    <!-- Get items from this project last so that they will be copied last. -->
    <CreateItem
        Include="@(ContentWithTargetPath->'%(FullPath)')"
        Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(_EmbeddedResourceWithTargetPath->'%(FullPath)')"
        Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(Compile->'%(FullPath)')"
        Condition="'%(Compile.CopyToOutputDirectory)'=='Always' or '%(Compile.CopyToOutputDirectory)'=='PreserveNewest'">
        <Output TaskParameter="Include" ItemName="_CompileItemsToCopy"/>
    </CreateItem>
    <AssignTargetPath Files="@(_CompileItemsToCopy)" RootFolder="$(MSBuildProjectDirectory)">
        <Output TaskParameter="AssignedFiles" ItemName="_CompileItemsToCopyWithTargetPath" />
    </AssignTargetPath>
    <CreateItem Include="@(_CompileItemsToCopyWithTargetPath)">
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_CompileItemsToCopyWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_CompileItemsToCopyWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>

    <CreateItem
        Include="@(_NoneWithTargetPath->'%(FullPath)')"
        Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='Always' or '%(_NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"
            >
        <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectoryAlways"
                Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
        <Output TaskParameter="Include" ItemName="_SourceItemsToCopyToOutputDirectory"
                Condition="'%(_NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
    </CreateItem>
</Target>

Po zastosowaniu tego obejścia okazało się, że wykonalne jest posiadanie aż> 120 projektów w jednym rozwiązaniu, co ma tę główną zaletę, że kolejność kompilacji projektów może być nadal określana przez VS zamiast robić to ręcznie, dzieląc rozwiązanie .


Czy możesz opisać wprowadzone zmiany i dlaczego? Moje gałki oczne są zbyt zmęczeni po długim dniu kodowania spróbować inżynierii wstecznej to sam :)
Charlie Flowers

Co powiesz na próbę skopiowania i wklejenia tego ponownie - TAK zepsuło jak 99% tagów.
ZXX

@Charlie Flowers, @ZXX zredagował tekst tak, aby był opisem, nie mógł ładnie ustawić XML w układzie.
Bas Bossink

1
Z Microsoft.Common.targets: GetCopyToOutputDirectoryItems Pobierz wszystkie elementy projektu, które mogą wymagać przeniesienia do katalogu wyjściowego. Obejmuje to bagaż z projektów, do których istnieją odniesienia przejściowe. Wydawałoby się, że ten cel oblicza pełne przechodnie zamknięcie elementów treści dla wszystkich przywoływanych projektów; jednak tak nie jest.
Brans Ds

2
Zbiera tylko elementy treści od swoich bezpośrednich elementów podrzędnych, a nie od dzieci dzieci. Powodem tego jest to, że ProjectReferenceWithConfiguration lista, która jest używana przez _SplitProjectReferencesByFileExistence, jest wypełniana tylko w bieżącym projekcie i jest pusta w elementach podrzędnych. Pusta lista powoduje, że _MSBuildProjectReferenceExistent jest pusta i przerywa rekursję. Więc wydaje się to nieprzydatne.
Brans Ds

32

Proponuję przeczytać artykuły Patrica Smacchii na ten temat:

Projekty CC.Net VS opierają się na opcji kopiowania lokalnego zestawu referencyjnego ustawionej na true. [...] Nie tylko znacznie wydłuża to czas kompilacji (x3 w przypadku NUnit), ale także zakłóca środowisko pracy. Wreszcie, co nie mniej ważne, powoduje to ryzyko wystąpienia potencjalnych problemów z wersjonowaniem. Btw, NDepend wyemituje ostrzeżenie, jeśli znajdzie 2 zestawy w 2 różnych katalogach o tej samej nazwie, ale nie o tej samej zawartości lub wersji.

Właściwe jest zdefiniowanie 2 katalogów $ RootDir $ \ bin \ Debug i $ RootDir $ \ bin \ Release i skonfigurowanie projektów VisualStudio do emitowania zestawów w tych katalogach. Wszystkie odwołania do projektu powinny odwoływać się do zestawów w katalogu debugowania.

Możesz również przeczytać ten artykuł, aby pomóc Ci zmniejszyć liczbę projektów i skrócić czas kompilacji.


1
Chciałbym móc polecić praktyki Smacchii z więcej niż jednym głosem za! Kluczowe jest zmniejszenie liczby projektów, a nie dzielenie rozwiązania.
Anthony Mastrean

23

Sugeruję, aby kopiować local = false dla prawie wszystkich projektów z wyjątkiem tego, który znajduje się na górze drzewa zależności. A dla wszystkich odniesień w tym na najwyższym zestawie kopiuj local = true. Widzę, że wiele osób sugeruje udostępnienie katalogu wyjściowego; Myślę, że to okropny pomysł oparty na doświadczeniu. Jeśli Twój projekt startowy zawiera odwołania do biblioteki DLL, do której odwołuje się inny projekt, w pewnym momencie wystąpi naruszenie zasad dostępu \ udostępniania, nawet jeśli kopia local = false na wszystkim się nie powiedzie. Ten problem jest bardzo irytujący i trudny do wyśledzenia. Całkowicie sugeruję trzymanie się z dala od katalogu wyjściowego fragmentu i zamiast umieszczania projektu na górze łańcucha zależności, zapisuj potrzebne zestawy do odpowiedniego folderu. Jeśli nie masz projektu na górze, wtedy zasugerowałbym kopię post-build, aby wszystko było we właściwym miejscu. Starałbym się również pamiętać o łatwości debugowania. Wszelkie projekty exe, które nadal zostawiam copy local = true, więc debugowanie F5 będzie działać.


2
Miałem ten sam pomysł i miałem nadzieję, że znajdę tu kogoś, kto myślałby w ten sam sposób; jestem jednak ciekawy, dlaczego ten post nie ma więcej głosów za. Osoby, które się nie zgadzają: dlaczego się nie zgadzasz?
bwerks

Nie, to nie może się zdarzyć, chyba że ten sam projekt jest budowany dwa razy, dlaczego miałby zostać nadpisany \ naruszenie zasad dostępu \ udostępniania, jeśli został zbudowany raz i nie kopiuje żadnych plików?
paulm

To. Jeśli przepływ pracy deweloperskiej wymaga zbudowania jednego projektu sln, podczas gdy inny projekt rozwiązania jest uruchomiony, posiadanie wszystkiego w tym samym katalogu wyjściowym będzie bałaganem. W tym przypadku znacznie lepiej jest oddzielić wykonywalne foldery wyjściowe.
Martin Ba

10

Masz rację. CopyLocal całkowicie zabije Twój czas tworzenia. Jeśli masz duże drzewo źródeł, powinieneś wyłączyć CopyLocal. Niestety nie jest to tak łatwe, jak powinno być, aby go czysto wyłączyć. Odpowiedziałem dokładnie na to pytanie dotyczące wyłączania CopyLocal w Jak nadpisać ustawienie CopyLocal (Prywatne) dla odwołań w .NET z MSBUILD . Sprawdź to. Jak również najlepsze rozwiązania dotyczące dużych rozwiązań w programie Visual Studio (2008).

Oto więcej informacji na temat CopyLocal, jak to widzę.

CopyLocal został zaimplementowany tak, aby wspierać lokalne debugowanie. Przygotowując aplikację do pakowania i wdrażania, należy skompilować projekty w tym samym folderze wyjściowym i upewnić się, że masz wszystkie potrzebne odniesienia.

O tym, jak radzić sobie z budowaniem dużych drzew źródłowych, pisałem w artykule MSBuild: najlepsze praktyki tworzenia niezawodnych kompilacji, część 2 .


8

Moim zdaniem posiadanie rozwiązania obejmującego 100 projektów to DUŻY błąd. Prawdopodobnie możesz podzielić swoje rozwiązanie na prawidłowe logiczne małe jednostki, upraszczając w ten sposób zarówno konserwację, jak i kompilację.


1
Bruno, zobacz moje dodatkowe pytanie powyżej - jeśli włamiemy się na mniejsze pliki .sln, jak poradzisz sobie z aspektem Debug vs. Release, który jest następnie wypalany w ścieżce podpowiedzi w moich odniesieniach?
Dave Moore

1
Zgadzam się z tym punktem, rozwiązanie, z którym pracuję, ma ~ 100 projektów, z których tylko kilka ma więcej niż 3 klasy, czasy kompilacji są szokujące, w wyniku czego moi poprzednicy podzielili rozwiązanie na 3, co całkowicie psuje znalezisko wszystkie referencje i refaktoryzacja. Całość mogłaby zmieścić się w kilku projektach, które powstałyby w kilka sekund!
Jon M

Dave, dobre pytanie. Tam, gdzie pracuję, mamy skrypty budujące takie rzeczy, jak budowanie zależności dla danego rozwiązania i umieszczanie plików binarnych w miejscu, w którym dane rozwiązanie może je pobrać. Te skrypty są sparametryzowane zarówno dla kompilacji debugowania, jak i wydania. Wadą jest dodatkowy czas na zbudowanie wspomnianych skryptów, ale można ich ponownie użyć w aplikacjach. To rozwiązanie działa dobrze według moich standardów.
jyoungdev

7

Dziwię się, że nikt nie wspomniał o używaniu twardych linków. Zamiast kopiować pliki, tworzy twarde łącze do oryginalnego pliku. Oszczędza to miejsce na dysku, a także znacznie przyspiesza kompilację. Można to włączyć w wierszu poleceń z następującymi właściwościami:

/ p: CreateHardLinksForAdditionalFilesIfPossible = true; CreateHardLinksForCopyAdditionalFilesIfPossible = true; CreateHardLinksForCopyFilesToOutputDirectoryIfPossible = true; CreateHardLinksForCopyLocalIfPossible = true; CreateForHardLinksForCopyFilesToOutputDirectoryIfPossible = true; CreateHardLinksForCopyLocalIfPossible = true;

Możesz również dodać to do centralnego pliku importu, aby wszystkie Twoje projekty również mogły uzyskać tę korzyść.


5

Jeśli masz strukturę zależności zdefiniowaną za pomocą odwołań do projektu lub zależności na poziomie rozwiązania, możesz bezpiecznie wyłączyć „Kopiuj lokalnie”, powiedziałbym nawet, że jest to najlepsza praktyka do zrobienia, ponieważ pozwoli ci to użyć MSBuild 3.5 do równoległego uruchamiania kompilacji ( via / maxcpucount) bez potykania się różnych procesów o siebie podczas próby kopiowania zestawów, do których istnieją odwołania.


4

naszą „najlepszą praktyką” jest unikanie rozwiązań w wielu projektach. Mamy katalog o nazwie „matrix” z aktualnymi wersjami zestawów, a wszystkie odwołania pochodzą z tego katalogu. Jeśli zmienisz jakiś projekt i możesz powiedzieć „teraz zmiana jest zakończona”, możesz skopiować zespół do katalogu „matrix”. Zatem wszystkie projekty zależne od tego zestawu będą miały bieżącą (= najnowszą) wersję.

Jeśli masz kilka projektów w rozwiązaniu, proces kompilacji jest znacznie szybszy.

Możesz zautomatyzować krok „kopiuj zestaw do katalogu macierzy” za pomocą makr programu Visual Studio lub za pomocą „menu -> narzędzia -> narzędzia zewnętrzne ...”.



2

Ustawienie CopyLocal = false skróci czas kompilacji, ale może powodować różne problemy podczas wdrażania.

Istnieje wiele scenariuszy, w których musisz ustawić opcję Copy Local na True, np

  • Projekty na najwyższym poziomie,
  • Zależności drugiego poziomu,
  • Biblioteki DLL wywoływane przez odbicie

Możliwe problemy opisane w pytaniach SO
Kiedy należy ustawić wartość true dla funkcji copy-local, a kiedy nie? ”,
Komunikat o błędzie„ Nie można załadować jednego lub więcej żądanych typów. Pobierz właściwość LoaderExceptions, aby uzyskać więcej informacji ”. "
I   Aaron-stainback jest odpowiedź  na to pytanie.

Moje doświadczenie z ustawieniem CopyLocal = false NIE powiodło się. Zobacz mój post na blogu „Nie zmieniaj odniesień do projektu„ Kopiuj lokalnie ”na fałsz, chyba że rozumiesz podciągi”.

Czas potrzebny na rozwiązanie problemów przeważa nad korzyściami wynikającymi z ustawienia copyLocal = false.


Ustawienie CopyLocal=Falsez pewnością spowoduje pewne problemy, ale są na to rozwiązania. Powinieneś także poprawić formatowanie swojego bloga, jest on ledwo czytelny, a stwierdzenie, że „Zostałem ostrzeżony przez <losowego konsultanta> z <losowa firma> o możliwych błędach podczas wdrażania” nie jest argumentem. Musisz się rozwijać.
Suzanne Dupéron

@ GeorgesDupéron, Czas potrzebny na rozwiązanie problemów przeważa nad korzyściami wynikającymi z ustawienia copyLocal = false. Odwołanie się do konsultanta nie jest argumentem, ale uznaniem, a mój blog wyjaśnia, na czym polegają problemy. Dziękujemy za przesłanie opinii. formatowanie, naprawię to.
Michael Freidgeim

1

Staram się budować do wspólnego katalogu (np. \ Bin), więc mogę tworzyć małe rozwiązania testowe.


1

Możesz spróbować użyć folderu, w którym zostaną skopiowane wszystkie zespoły współdzielone między projektami, a następnie utwórz zmienną środowiskową DEVPATH i ustaw ją

<developmentMode developerInstallation="true" />

w pliku machine.config na stacji roboczej każdego programisty. Jedyne, co musisz zrobić, to skopiować każdą nową wersję do swojego folderu, w którym wskazuje zmienna DEVPATH.

Jeśli to możliwe, podziel również rozwiązanie na kilka mniejszych.


Ciekawe ... Jak to działałoby z wersjami debugowania i wydania?
Dave Moore

Nie jestem pewien, czy istnieje odpowiednie rozwiązanie do ładowania zestawów debugowania / zwalniania za pośrednictwem DEVPATH, jest przeznaczone tylko do użytku w przypadku zestawów udostępnionych, nie polecałbym go do tworzenia regularnych kompilacji. Należy również pamiętać, że wersja zestawu i GAC są zastępowane podczas korzystania z tej techniki.
Aleksandar

1

Może to nie jest najlepsza praktyka, ale tak właśnie pracuję.

Zauważyłem, że Managed C ++ zrzuca wszystkie swoje pliki binarne do $ (SolutionDir) / 'DebugOrRelease'. Więc porzuciłem tam również wszystkie moje projekty C #. Wyłączyłem również opcję „Kopiuj lokalnie” wszystkich odniesień do projektów w rozwiązaniu. Zauważyłem znaczną poprawę czasu kompilacji w moim małym rozwiązaniu dla 10 projektów. To rozwiązanie jest mieszanką projektów C #, zarządzanego języka C ++, natywnego języka C ++, usługi sieci web języka C # i projektów instalatora.

Może coś jest zepsute, ale ponieważ to jedyny sposób, w jaki pracuję, nie zauważam tego.

Byłoby interesujące dowiedzieć się, co łamię.


0

Zwykle wystarczy skopiować lokalnie, jeśli chcesz, aby projekt korzystał z biblioteki DLL znajdującej się w Twoim Bin, a nie z tego, co jest gdzie indziej (GAC, inne projekty itp.)

Zgodziłbym się z innymi ludźmi, że powinniście również spróbować, jeśli to w ogóle możliwe, zerwać z tym rozwiązaniem.

Możesz również użyć Configuration Manager, aby stworzyć różne konfiguracje kompilacji w ramach tego jednego rozwiązania, które będzie budować tylko określone zestawy projektów.

Wydawałoby się dziwne, gdyby wszystkie 100 projektów opierało się na sobie nawzajem, więc powinieneś być w stanie je rozbić lub użyć Configuration Manager, aby sobie pomóc.


0

Możesz mieć odniesienia do projektów wskazujące na wersje debugowania bibliotek dll. Następnie w swoim skrypcie msbuild możesz ustawić /p:Configuration=Release, dzięki czemu będziesz mieć wersję swojej aplikacji i wszystkie zestawy satelickie.


1
Bruno - tak, działa to z referencjami do projektów, co jest jednym z powodów, dla których zdecydowaliśmy się na 100 rozwiązań projektowych w pierwszej kolejności. Nie działa w przypadku odniesień, w których przeglądam wstępnie zbudowane wersje debugowania - kończę z aplikacją do wydania opartą na zestawach debugowania, co jest problemem
Dave Moore

4
Edytuj plik projektu w edytorze tekstu i użyj $ (Configuration) w swojej HintPath, np. <HintPath> .. \ output \ $ (Configuration) \ test.dll </HintPath>.
ultravelocity


0

Jeśli referencja nie jest zawarta w GAC, musimy ustawić Copy Local na true, aby aplikacja działała, jeśli mamy pewność, że referencja zostanie preinstalowana w GAC, to możemy ustawić ją na false.


0

Cóż, na pewno nie wiem, jak działają problemy, ale miałem kontakt z rozwiązaniem do kompilacji, które pomogło sobie w taki sposób, że wszystkie utworzone pliki były umieszczane na ramdysku za pomocą dowiązań symbolicznych .

  • c: \ folder rozwiązania \ bin -> ramdysk r: \ folder rozwiązania \ bin \
  • c: \ folder rozwiązania \ obj -> ramdysk r: \ folder rozwiązania \ obj \

  • Możesz również wskazać programowi Visual Studio, którego katalogu tymczasowego może użyć do kompilacji.

Właściwie to nie wszystko, co zrobił. Ale to naprawdę uderzyło w moje rozumienie wydajności.
100% wykorzystania procesora i ogromny projekt w mniej niż 3 minuty ze wszystkimi zależnościami.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.