|
I got my answer, thanks.
I have one more question. You said "it blocks the rest of the method" yes the following codes will not be executed until the job is complete, what exactly is waiting here? I guess it was a deep question
|
|
|
|
|
Behind the scenes, your async method will be rewritten into a state machine. Whenever you await something, so long as that operation doesn't complete immediately, the rest of your method will be signed up as a "continuation" to run when that asynchronous operation completes.
As a simple example:
public async Task Foo()
{
Console.WriteLine("Start...");
await Task.Delay(1000);
Console.WriteLine("Done.");
} would (logically) turn into something more like:
public Task Foo()
{
Console.WriteLine("Start...");
return Task.Delay(1000).ContinueWith(_ => Console.WriteLine("Done."));
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
Hello there!
I am new to this forum and I am also a beginner C# coder. I am trying to make a paid app but I will need to make a license key system. Do anyone know any tutorials I can use for this?
It should check the Realtime DB for the license key and check get the processor ID (or any other unique identifier) then it will check your device for the unique id and boom! you are in.
Or if there are any other tutorials please do link them in the comments below thanks!
|
|
|
|
|
|
I'm working on an ASP.NET Core web API and SQLite database. I have created a table for users of my application. The rule is that each user can send a message to some other users (creating White-List). I use the following model for Users:
public class UserModel
{
[Key]
public int UserID { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Role { get; set; }
public Department Department { get; set; }
}
My desired table is:
User-SubUser table
------------------------------------
UserID ReceiverUserID
------ --------------
23 11
42 11
19 -
34 23
Note that the IDs mentioned above are the UserIDs from the User table. This table says that users 23 and 42 can send a message to user 11, user 34 can send a message to user 23, and user 19 cannot send message to anyone.
How can I make a model for creating such a table?
|
|
|
|
|
Having "19" in the table is pointless and just complicates the situation.
The simplest "model" is to simply join "Users" and "User-SubUser" when you need to; e.g. who can x send to (join on UserID), or who might x receive from (join on ReceiverUserID).
If you want the (database) server to maintain "referential integrity", that's another story.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Ok, Considering the final table only includes pairs (removing 19), how can I do joining using C# and EF Core?
|
|
|
|
|
Your "vehicle" in this case is LINQ.
Complex Query Operators - EF Core | Microsoft Docs
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I meant how I can create a UserSubUser table. I need a C# model to create this table (Code-First approach). UserIDs in the UserSubUser table should be linked to the UserModel table.
|
|
|
|
|
No, they don't. You need to look up normalization, and apply dem rules to your database.
If all that is required is whitelisting, then just have a table with users who are allowed to message each other. You think from C#; but the layer your working in is SQL, where you need to think SQL. Normalize them tables, work from there.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
|
I've finished an application in C# using Visual Studio 2022 and need to make an installer for it. I used Microsoft Visual Studio Installer Projects extension and could create the installer which works fine. But I need something else: during instalation, it's necessary to create a folder, then a file and save this file into that folder. But I don't know how to do this in this installer. Does anybody has a solution for this? Thanks.
|
|
|
|
|
Your app should be able to create a folder and file; there's no reason for an installer to do it as you describe it ("the install works fine").
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
C# you try it's remain a fewer ways for you
|
|
|
|
|
I want to create a memory stream as follows
[1byte][4bytes][n bytes][4 bytes][n bytes][4 bytes][n bytes] ....ect
my first stream consisted of [0][12][Hello World.]
_packetWriter.WriteOpCode((byte)opCode);
_packetWriter.WriteMessage("Hello World.");
_client.Client.Send(_packetWriter.GetPacketBytes());
when I read it back I get the following, and when I look at the byte arrays I'm seeing some bytes from the previous chunk
10/09/2022 11:39:00 : Opcode Found With Value 0
10/09/2022 11:39:00 : Chunk Found With Value 12
10/09/2022 11:39:00 : Message Found With Value
Hello Worl
can anybody help
thanks madaxe
public class PacketWriter : BinaryWriter
{
public MemoryStream MemoryStream;
public BinaryWriter BinaryWriter;
public PacketWriter()
{
MemoryStream = new MemoryStream();
BinaryWriter = new BinaryWriter(MemoryStream);
}
public void WriteOpCode(byte opCode)
{
MemoryStream.WriteByte(opCode);
}
public void WriteNextChunckSize(int chunkSize)
{
BinaryWriter.Write((Int32)chunkSize);
}
public void WriteMessage(string message)
{
WriteNextChunckSize(message.Length);
BinaryWriter.Write(message);
}
public byte[] GetPacketBytes()
{
return MemoryStream.ToArray();
}
}
public class PacketReader : BinaryReader
{
private NetworkStream _memoryStream;
public PacketReader(NetworkStream memoryStream) : base(memoryStream)
{
_memoryStream = memoryStream;
}
public int ReadOpCode()
{
return _memoryStream.ReadByte();
}
public string ReadMessage(int chunkSize)
{
byte[] readMessage;
readMessage = new byte[chunkSize];
_memoryStream.Read(readMessage, 0, chunkSize);
var message = Encoding.ASCII.GetString(readMessage);
return message;
}
public int ReadChunkSize()
{
byte[] readChunkSize;
readChunkSize = new byte[4];
_memoryStream.Read(readChunkSize, 0, 3);
return BitConverter.ToInt32(readChunkSize, 0);
}
}
|
|
|
|
|
BinaryWriter.Write(string) writes a length-preceded string to the stream, with the length encoded as a variable-length integer (7 bits per block and a continuation bit). So some extra stuff appeared in your stream that you didn't count on.
BinaryWriter.Write(string) is most easily "mirrored" by using BinaryReader.ReadString in the decoder. Of course, you can also handle the length manually, but then you should probably also handle the encoding and write raw bytes to the stream to start with.
This is also wrong: _memoryStream.Read(readChunkSize, 0, 3); reading 3 bytes instead of 4. Why not use BinaryReader , it's simpler and less error prone.
By having written one extra byte per mistake (the extra length byte that BinaryWriter.Write(string) wrote, could have been more bytes for longer strings) and by having read one byte too few, a two byte discrepancy was created. Actually you should find that there are two unprintable characters at the start of your string, since it still should be 12 bytes, just not quite the right 12 bytes.
|
|
|
|
|
sure enough _memoryStream.Read(readChunkSize, 0, 4); fixed part of the problem and also changing the Write message as below fixed the issue.
but I want to use BinaryReader since I'm using BinaryWriter
the behavior I'm seeing is I can consecutively call ReadByte and it will read each byte in turn without me having to define position within the stream, which I don't understand.
so how do is use BinaryReader to read specific blocks of bytes, 2->6, and 7->19
thanks
Madaxe
public void WriteMessage(string message)
{
WriteNextChunckSize(message.Length);
byte[] byteArray = Encoding.UTF8.GetBytes(message);
BinaryWriter.Write(byteArray);
}
|
|
|
|
|
You can do some dummy reads of suitable sizes, discard the results, and then call the suitable Read method when the position of the stream is at the intended location. Or you can set the position of the underlying stream directly, and then read with the BinaryReader. Unfortunately both of these feel a bit like a hack, IMO there should have been some method on BinaryReader to skip a number of bytes, but that doesn't exist.
|
|
|
|
|
Hello,
I have a problem with a self programmed windows service for .Net 6 that inherits from BackgroundService:
namespace WooComMesserschmidt
{
internal class Worker : BackgroundService
{
private readonly HttpClient Client = new()
private string BaseAddress = string.Empty;
private readonly IConfiguration Configuration;
private string ConfigFile = string.Empty;
private readonly Dictionary<string, dynamic?> _ConfigPar;
internal static Dictionary<string, string> ConfigPar = new();
private readonly ILogger<Worker> _logger;
public struct LogInfo
{
public ILogger<Worker>? Logger;
public string? LogFile;
public LogInfo(ILogger<Worker>? logger, string logfile)
{
Logger = logger;
LogFile = logfile;
}
}
public static LogInfo logInfo;
public Worker(ILogger<Worker> logger, IConfiguration configuration, Dictionary<string, dynamic?> configpar)
{
Configuration = configuration;
_ConfigPar = configpar;
_logger = logger;
Init();
}
...
In the method "Init()" relatively extensive tasks take place (on my PC it takes about 2 seconds). If these are through, it goes on here:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (int.TryParse(ConfigPar[cpQueryInterval], out int QueryInterval) == false)
{
QueryInterval = QueryIntervalStd;
Log.LogInformation(logInfo, $"Abfrageintervall konnte nicht ermittelt werden. Es wird daher der Standardwert von {QueryInterval} Millisekunden verwendet. Prüfen Sie die Angaben in der Parameterdatei.");
}
Log.LogInformation(logInfo, $"{Process.GetCurrentProcess().ProcessName} gestartet.");
Log.LogInformation(logInfo, $"Worker arbeitet mit Abfrageintervall von {QueryInterval} Millisekunden.");
while (stoppingToken.IsCancellationRequested == false)
{
await ProcessNewOrders();
await UpdateProducts();
Dhl_Polling();
await Task.Delay(QueryInterval, stoppingToken);
}
}
...
The service is supposed to fetch orders from an eShop every few minutes, update items and process DHL shipments.
Well, when I start the program manually in the command line (i.e. not as a service), everything works as expected. Now I have registered the program as a service and every time I try to start the service I get the following error: Error 1053: The service did not respond to the start or control request in a timely fashion
We started everything in Main:
private static async Task<int> Main(string[] args)
{
try
{
IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = ServiceName;
})
.ConfigureServices(services =>
{
services.AddSingleton<Dictionary<string, dynamic?>> (_ConfigPar);
services.AddHostedService<Worker>();
})
.Build();
await host.RunAsync();
Log.LogInformation((LogInfo)_ConfigPar[cpLogInfo], $"{Process.GetCurrentProcess().ProcessName} beendet.");
if (Debugger.IsAttached == true)
{
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine($"{ex}{Environment.NewLine}{Environment.NewLine}");
...
How do I proceed to avoid this error?
Many thanks
René
|
|
|
|
|
That would suggest that your startup code is taking too long. You mention the Init method contains "extensive tasks" - I'd suggest moving some or all of those to the start of the ExecuteAsync method instead.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you. That's exactly what I did yesterday, but the error remained. I will try again, but now rested
|
|
|
|
|
OK, problem solved. The error message had driven me astray and I was looking in the wrong place for the cause of the error. Now I proceeded systematically step by step: at the very beginning, the service crashes without doing anything. The error was due to the "displayname" of the service - this may be maximum 80 characters long, while I used 110 characters. I didn't know that and the error message also said something completely different.
Thanks for your help! The weekend is saved!
René
|
|
|
|
|
Repo: https://github.com/Charles-CarM/Battleship
I am currently building my battleship console application in C#. I have prior experience
building projects with Vanilla JS and in React. I went through a tutorial on C# and could
grasp most of the concepts pretty well. I have jumped into project building because I know
this is where the maximum amount of growth will be as a developer. With that being said I
will lay out the issues arising in my application.
requirements
* the ship has a length of 5
* ship will be randomly assigned on a 10X10 grid
* when the ship is hit five times it is sunk and game is over
I am having trouble choosing the best way to implement the 10x10 gameboard grid. With
some searching on the web I have came across the DataTable class, which allows for rows
and columns to be set in a table(I believe this to be the better approach), and I have attempted
to get them displayed in the Console below. Also I know that I can create a 10x10 grid with
a 2D array using int[,] grid = [10,10]; however I have realized that I can't assign the random values for the ship with an already populated array. I would like to get some feedback on how
I can move forward with creation of the gameboard, and random assignment of the ship on the board.
I know this post and my code are a little messy so please excuse me on that part. Any solutions or suggestions you recommend for me moving forward are welcomed and greatly appreciated. Hope you are very well wherever you may be.
using System.Data;
namespace Battleship
{
class Program
{
static void Main(string[] args)
{
GamePlay ship = new GamePlay("ten", "fast ship", 350);
Console.ReadLine();
GreetUser();
DataTable gameBoard = new DataTable("Battleship");
DataColumn columnA = new DataColumn("A");
DataColumn columnB = new DataColumn("B");
DataColumn columnC = new DataColumn("C");
DataColumn columnD = new DataColumn("D");
DataColumn columnE = new DataColumn("E");
DataColumn columnF = new DataColumn("F");
DataColumn columnG = new DataColumn("G");
DataColumn columnH = new DataColumn("H");
DataColumn columnI = new DataColumn("I");
DataColumn columnJ = new DataColumn("J");
gameBoard.Columns.Add(columnA);
gameBoard.Columns.Add(columnB);
gameBoard.Columns.Add(columnC);
gameBoard.Columns.Add(columnD);
gameBoard.Columns.Add(columnE);
gameBoard.Columns.Add(columnF);
gameBoard.Columns.Add(columnG);
gameBoard.Columns.Add(columnH);
gameBoard.Columns.Add(columnI);
gameBoard.Columns.Add(columnJ);
DataRow row1 = gameBoard.NewRow();
DataRow row2 = gameBoard.NewRow();
DataRow row3 = gameBoard.NewRow();
DataRow row4 = gameBoard.NewRow();
DataRow row5 = gameBoard.NewRow();
DataRow row6 = gameBoard.NewRow();
DataRow row7 = gameBoard.NewRow();
DataRow row8 = gameBoard.NewRow();
DataRow row9 = gameBoard.NewRow();
DataRow row10 = gameBoard.NewRow();
row1["A"] = 0;
row1["B"] = 0;
row1["C"] = 0;
row1["D"] = 0;
row1["E"] = 0;
row1["F"] = 0;
row1["G"] = 0;
row1["H"] = 0;
row1["I"] = 0;
row1["J"] = 0;
gameBoard.Rows.Add(row1);
gameBoard.Rows.Add(row2);
gameBoard.Rows.Add(row3);
gameBoard.Rows.Add(row4);
gameBoard.Rows.Add(row5);
gameBoard.Rows.Add(row6);
gameBoard.Rows.Add(row7);
gameBoard.Rows.Add(row8);
gameBoard.Rows.Add(row9);
gameBoard.Rows.Add(row10);
for(int j = 0; j < gameBoard.Rows.Count; j++)
{
for (int i = 0; i < gameBoard.Columns.Count; i++)
{
Console.WriteLine(gameBoard.Columns[i].ColumnName + " ");
Console.WriteLine(gameBoard.Rows[j].ItemArray[i]);
}
}
Console.ReadLine();
string coords;
int[,] numberGrid =
{
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 },
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
{ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 },
{ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 },
{ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },
{ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 },
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },
{ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90 },
{ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100 }
};
int[,] freshGrid = new int[10, 10];
for(int j = 0; j < freshGrid.Length; j++)
{
coords = Convert.ToString(j);
Console.Write(coords);
}
Console.ReadLine();
Console.WriteLine(freshGrid[3,4]);
Console.ReadLine();
Random random = new Random();
int newShip = random.Next();
Console.ReadLine();
Console.WriteLine("\nEnter guess: ");
int guess = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"\nYou guessed: {guess}");
Console.ReadLine();
}
static void GreetUser()
{
Console.WriteLine("Welcome to Battle! press Enter ");
Console.ReadLine();
Console.WriteLine("Enter username: ");
string username = Console.ReadLine();
Console.WriteLine($"\nLet's begin {username}!");
}
}
}
|
|
|
|
|
Why are you using a DataTable? It's a bit of a sledgehammer to crack a nut ...
You need a 10 x 10 area of "squares" which can contain four values: Empty, Ship, Hit, and Miss. So the simplest way to do that is you create an enum that has all of those values:
public enum Square
{
Empty,
Ship,
Hit,
Miss,
}
You can then create an array of that:
Square[,] MyBoard = new Square[10,10]; Or two:
Square[,] HisBoard = new Square[10,10]; You can now reference any particular Square via indexes:
if (MyBoard[x, y] == Square.Ship)
{
MyBoard[x, y] = Square.Hit;
...
} Create a method to clear a board:
public static Square[,] Clear(Square[,] board)
{
for (int x = 0; x < board.GetLength(0); x++)
{
for (int y = 0; y < board.GetLength(1); y++)
{
board[x, y] = Square.Empty;
}
}
return board;
} And you can start getting ready for a new game:
Square[,] MyBoard = new Square[10,10];
Square[,] HisBoard = new Square[10,10];
Clear(MyBoard);
Clear(HisBoard); Then just write another method to load your ships in: it accepts a board as a parameter, calls Clear. and then decides where to put the ships. (Initially, I'd try to write it using "single space" ships to make the code easier, then start working on the more complex shapes you really need).
In fact what I'd do is more complex than that: I'd encapsulate the Square array in a class called Board, several ship classes (Carrier, BattleShip, Cruiser, Submarine, Destroyer) derived from a base Ship class) and let it handle the mundane stuff so that most of the time you are manipulating Board objects:
MyBoard.place(myDestroyer, x, y, Orientation.Horizontal);
MyBoard.Bomb(6, 7); But if you haven't reached classes and instances yet then a basic array will be fine.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|