ואגב, למי שלא אוהב לשתף קטעי קוד שלו עם GitHub, מומלץ לבטל את הסימון באפשרות: 'Allow GitHub to use my code snippets from the code editor for product improvements', בעמוד ההגדרות.

קומפיונט
-
GitHub Copilot עכשיו בחינם -
Debugging על ViewModel ב-WPF@yossiz גם אני נתקל בבעיות האלו, ולפעמים אפילו התוכנה נסגרת מבלי לציין שום exception, קשה לשחזר את זה כי זה קורה רק בפרויקטים גדולים עם קוד אסינכרוני, לדוגמא יש לי Task.Run שבתוכו יש try/catch שהוא נקרא ממתודה אסינכרונית אחרת שגם היא עוטפת אותו ב - try/catch, ואז עם כל הבלגן הזה פתאום נופלת לך שגיאה במקום לא ברור. בפרויקטים קטנים זה פשוט לא קורה.
לפעמים אפילו vs מציב לי את השגיאה בפונקציה שמריצה את ה thread הראשי באתחול האפליקציה.
-
שימוש נכון ב-await Task.Run ב-C#@pcinfogmach כתב בשימוש נכון ב-await Task.Run ב-C#:
כמו"כ קראתי כמה פעמים על משהו שנקרא תנאי תחרות (Race Condition) כשמשתמשים ב-Multithreading - אני חייב לומר שלא בדיוק הבנתי את הנושא.
קח את הקוד הבא:
var count = 0; void Increment() { for (var i = 0; i < 1_000_000; i++) { count++; } } var task1 = Task.Run(Increment); var task2 = Task.Run(Increment); await Task.WhenAll([task1, task2]); Console.WriteLine(count);
הקוד הזה מריץ במקביל שני פונקיות שמקדמות את count במיליון, אם תצפה ש count יהיה שווה לשני מליון אחרי ההרצה, אז אתה תתפלא לראות שבכל הרצה מודפס ערך שונה, ואף פעם לא שני מליון.
הסיבה לזה טמונה לדרך הפעולות של המעבד. הקוד
++count
נראה פשוט אבל מורכב מכמה פעולות:
א. קריאת הערך של count
ב. חישוב הערך החדש
ג. כתיבת הערך החדש ל - countבגלל שהפעולות מתבצעות במקביל אז כשהמעבד עובר בין ה - threadים (בתהליך שנקרא context-switch) זה גם יכול לקרות באמצע הפעולות הנ"ל, לדוגמא אחרי פעולות א' ו-ב' המעבד עובר ל - thread השני ואז התוצאה היא שאיבדנו קידום של ספרה אחת.
אם תשנה את שורה 7 לזה:
Interlocked.Increment(ref count);
או לזה:
lock(...) { count++; }
תראה שהתוצאה היא שני מליון כמצופה, וזה קורה בגלל שנעלנו את הקטע הקריטי שבו אנחנו צריכים שיהיה סינכרון בין שני ה threadים, ולא יבוצע עדכון במקביל, במילים אחרות, במקרה הזה זה מחייב שפעולות א' ב' ו-ג' יתבצעו ביחד ולא יתפרקו באמצע.
אני יודע שזה מסובך אבל ניסיתי להסביר כמה שהתאפשר לי.
-
Debugging על ViewModel ב-WPF@pcinfogmach כתב בDebugging על ViewModel ב-WPF:
ובפרט מה בדיוק עושה מה ש@Mordechai-0 אמר Enable Just my code
האופציה הזאת מאפשרת לדבג קוד חיצוני שאינו חלק מהפרוייקט שלך, לצורך הדוגמא: אם הכנסת break point באיזשהו מקום בקוד ואתה מתקדם שורה שורה עם F10 או F11, אז אם Enable Just my code מופעל F11 לא יכנס לפונציות שהם לא בקוד שלך, אם הוא מבוטל זה יכנס גם לקוד שהוא ממקור חיצוני באמצעות דה-קומפלציה (או source link).
בקשר ל-default, זכור לי שזה השתנה בין הגרסאות של visual studio.
-
הסרת שורות ריקות מ-string ב-C#@pcinfogmach
במקום:return string.Join("\n", nonEmptyLines);
עדיף:
return string.Join(Environment.NewLine, nonEmptyLines);
אני הייתי עושה את זה גם בשורה הראשונה במקום:
new[] { '\r', '\n' }
-
איך להשיג את האייקון של כל סוגי הקבצים בC#בדיוק לפני כמה זמן הייתי צריך לכתוב קוד שמחלץ תמונה ממוזערת מקובץ וידיאו, אז כתבתי את זה (וזה מתאים לכל סוגי הקבצים, גם לכוננים), היתרון שאפשר לקבל את התמונה בגודל שתרצה ועם עוד enum של אפשרויות.
זה הקוד:
public static class Shell { private static readonly Guid _s_imageFactoryShellId = new("BCC18B79-BA16-442F-80C4-8A59C30C463B"); public static byte[] GetImage(string path, ImageSize size, ShellItemGetImageOptions options) { if (OperatingSystem.IsWindows()) { if (SHCreateItemFromParsingName(path, 0, _s_imageFactoryShellId, out var imageFactory) != 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (imageFactory.GetImage(size, (int)options, out var hBitmap) != 0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } try { using var stream = new MemoryStream(); var bitmap = Image.FromHbitmap(hBitmap); bitmap.Save(stream, ImageFormat.Jpeg); return stream.ToArray(); } finally { DeleteObject(hBitmap); } } throw new PlatformNotSupportedException(); } } public enum ShellItemGetImageOptions { ResizeToFit = 0, BiggerSizeOk = 1, MemoryOnly = 2, IconOnly = 4, ThumbnailOnly = 8, InCacheOnly = 0x10, CropToSquare = 0x20, WideThumbnails = 0x40, IconBackground = 0x80, ScaleUp = 0x100 } public readonly struct ImageSize(int width, int height) { public int Width { get; } = width; public int Height { get; } = height; } internal static partial class Unmanaged { [GeneratedComInterface] [Guid("BCC18B79-BA16-442F-80C4-8A59C30C463B")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public partial interface IShellItemImageFactory { [PreserveSig] int GetImage(ImageSize size, int flags, out nint hBitmap); } [LibraryImport("Shell32", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)] public static partial int SHCreateItemFromParsingName(string pszPath, nint pbc, Guid riid, out IShellItemImageFactory ppv); [LibraryImport("Gdi32", SetLastError = true)] public static partial int DeleteObject(nint hObject); }
נ.ב.
זה הקוד הבסיסי, אפשר לשנות ולהתאים אותו למה שאתה צריך.
לא בדקתי אם זה עובד גם על מערכות windows יותר ישנות.
הקוד תואם ל NativeAOT (אם תשתמש בו בעתיד)
לא יודע אם הקוד הזה יעבוד ב net-framework. -
#C | הטמעת ממשקי COM במצב NativeAOTלאחר הרבה ניסיונות מצאתי בס"ד את הדרך ליישם את זה, אני שם את זה פה אם למישהו זה יהיה שימושי בעתיד.
א. הוספתי מחלקת עזר שתייצר ממשקי COM כדלהלן:
public static partial class ComActivator { [LibraryImport("ole32")] private static partial int CoCreateInstance( ref Guid clsid, nint pUnkOuter, int dwClsContext, ref Guid iid, [MarshalAs(UnmanagedType.Interface)] out object pObj ); public static TInterface ActivateClass<TInterface>(Guid clsid, Guid iid) { Debug.Assert(iid == typeof(TInterface).GUID); var hResult = CoCreateInstance(ref clsid, default, 1, ref iid, out var obj); if (hResult < 0) { Marshal.ThrowExceptionForHR(hResult); } return (TInterface)obj; } }
ב. למחלקה
ITaskbarList3
הוספתי את התכונהGeneratedComInterface
ג. ככה אני מקבל את האובייקט:
var clsid = Guid.Parse("56FDF344-FD6D-11D0-958A-006097C9A090"); // TaskBarList var iid = Guid.Parse("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF"); // ITaskBarList3 var taskbar = ComActivator.ActivateClass<ITaskbarList3>(clsid, iid);
קישור שעזר לי: https://learn.microsoft.com/en-us/dotnet/standard/native-interop/tutorial-comwrappers
נ.ב. מצאתי עוד פתרון עם
ComWrappers
אבל הפתרון הראשון עובד מצויין אז השתמשתי בו. -
עיצוב תוכנה כמו בווינדוס 11 -
#C | למה לא לרשת מ <List<Tבשרשור הזה דיברו על אובייקט ב-#C שמדמה טבלת נתונים, לא רציתי לסטות מהנושא אז פתחתי על זה נושא.
ההוספה שלי היא, שבעקרון לא כדי לבנות מחלקה שיורשת מ-
<List<T
בגלל כמה סיבות, אם זה מעניין משהו אפשר לעיין בלינקים הבאים:c# - Why not inherit from List<T>? - Stack Overflow
c# - Inheriting from List<T> - Stack Overflow -
BLAZOR - האם זה יעיל?@Y-Excel-Access כתב בBLAZOR - האם זה יעיל?:
BLAZOR זה יישום FULL STACK. יש לו שני חלקים, SERVER ו WEB ASSAMBLY
שים לב ש-Blazor Server ו-Blazor WebAssembly זה שני דברים שונים.
Blazor Server זה צד שרת מבוסס asp.net עם דפים בסינטקס שנקרא Razor, הקוד ב-#C רץ בשרת, והתקשורת בין הדפדפן לשרת נעשית עם SignalR.
Blazor WebAssembly זה גם דפי Razor, רק שהקוד #C רץ ממש בצד הלקוח עם זמן ריצה של NET. שיורד לדפדפן ונקרא בשם WebAssembly.ההבדל בתכלס הוא איפה רץ הקוד #C של דפי ה-Razor, בשרת או בדפדפן.
-
מה האלגוריתם ליצירת ההאש לסיסמה בווינדוס ?תאמת שאני קצת מתחיל לפקפק שזה הדרך ש-Windows מחשב את ההאש של הסיסמה, כי אני שם לב שאצלי הסיסמה היא תלוית רישיות, כלומר אם קבעתי את הסיסמה:
AA
אז הסיסמהaa
לא עוברת. לפי הדרך שצוינה לעיל הסיסמהaa
אמורה לעבור בלי בעיות, וצ"ע. -
אלגוריתם: סינון מערך (#C)@dovid זה פשוט מדהים...
אני בזבזתי על זה פונקצייה שלמה:
public static class DistinctByVersionExtensions { public static IEnumerable<Lazy<TSource, TSourceMetadata>> DistinctByVersion<TSource, TSourceMetadata>(this IEnumerable<Lazy<TSource, TSourceMetadata>> source, Func<TSourceMetadata, string> idSelector, Func<TSourceMetadata, double> versionSelector) { foreach (Lazy<TSource, TSourceMetadata> item in source) { string id = idSelector(item.Metadata); IEnumerable<Lazy<TSource, TSourceMetadata>> same_ids = source.Where(v => idSelector(v.Metadata) == id); if (same_ids.Any()) { double ver = versionSelector(item.Metadata); double max_ver = same_ids.Max(v => versionSelector(v.Metadata)); if (ver == max_ver) yield return item; } else { yield return item; } } } }
ולא חשבתי שזה כל כך פשוט..
אגב, יותר נחמד זה ככה:
.Select(x => x.OrderBy(y => y.version).Last());
במקום:
.Select(x => x.OrderByDescending(y => y.version).First());
ומגרסת 6.0 של NET. אפשר גם ככה:
.Select(x => x.MaxBy(y => y.version));
-
המחשב שלי עם ניצול של 40% מהRAM על ריק@MOSHEMOSE1 ככל שיש לך זיכרון פיזי יותר גדול, ככה windows מרגיש חופשי למלא אותו מבלי להשתמש בזכרון וירטואלי וכל מיני שיטות לחיסכון.
-
תוכנת תרגום אופליין V2@pcinfogmach כתב בתוכנת תרגום אופליין V2:
מישהו יכול לפרט קצת מהו בעצם קהל היעד של תוכנה זו? ולאיזה שימוש הוא נועד\נצרך?
בעיקר לאילו שרוצים תרגום משפטים אופליין.
לפי התגובות נראה שזוהי תוכנה עם פונטציאל אולי תעשה גיט...
חשבתי על זה, אם אני אדע שיש מישהו עם נכונות ויכולת לתרום לפיתוח אני אשקול להפוך את המאגר לציבורי.
אולי תעשה גיט...
(נ.ב. אתה כנראה מתכוון לגיטהב, כי גיט וגיטהב זה שני מושגים נפרדים)
-
תוכנת תרגום אופליין V2@מנחמן הסיבה שלא פרסמתי עד עכשיו את התוכנה זה בגלל שהיה חסר פיצ'רים שלא היה לי זמן להוסיף, אחרי שעבר הרבה זמן החלטתי לפרסם את התוכנה איך שהיא כדי שתהיה לתועלת אחרים, כשיהיה לי זמן אוסיף בע"ה פיצ'רים נוספים.
-
בקשה | תוכנה עדכנית להורדת ערוץ שלם מיוטיוב בנטפרי@פלורידה כתב בבקשה | תוכנה עדכנית להורדת ערוץ שלם מיוטיוב בנטפרי:
הקישור הזה כולל הורדה MP3
סתם ככה מומלץ להתקין גם את ffmpeg בשביל האיכות של הוידאו, בלי ffmpeg האיכות הכי גבוהה שאפשר להוריד היא 720p
-
בקשה | תוכנה עדכנית להורדת ערוץ שלם מיוטיוב בנטפרי -
בקשת מידע | פתיחת מסד הנתונים של ספריא אופליין בווינדוס@האדם-החושב
אני אנסה להסביר בקצרה מה אתה צריך לעשות.א. להתקין שרת מונגו לוקאלי על המחשב, אפשר להוריד מפה.
(כדי לבדוק אם אכן השרת פועל על המחשב אפשר להיכנס לדפדפן בכתובת http://localhost:27017/ ולראות אם הדף עובד ומציג טקסט כלשהו זה אומר שהשרת רץ על המחשב)ב. לבצע ייבוא של החומר למסד הנתונים (
mongorestore --drop
)ג. אני ממליץ לך להוריד את compass שזה ממשק גרפי לניהול מסדי נתונים של mongo, שם תוכל לראות את הנתונים וגם לעשות יבוא ויצוא בצורה נוחה.
בפתיחת התוכנה תיצור חיבור לשרת הלוקאלי ככה:
-
הוספת תיקיה מוכרת מותאמת אישית ב-Windows -
משחק שחמטאולי אפשר להגביל את זמן החשיבה שלו ברמות הנמוכות, באופן שיתאים למחשבים המהירים של היום.
אני מעלה גרסה עם שליטה על הרמה בשני פרמטרים:
הנה הקישור: ChessWithDepthאפשרות אחת זה עומק חישוב - כמה רובדים קדימה לחשב,
אפשרות שניה זה הקבצת הזמן המקסימאלי שהמנוע יכול לחשוב (באלפית השנייה).