- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 36
await using var sqlConnection = new SqlConnection(connectionString); using var sqlBulkCopy = new SqlBulkCopy(sqlConnection); using var csvDataReader = new CsvDataReader(csvPath); await sqlConnection.OpenAsync(); sqlBulkCopy.DestinationTableName = "GpsInfo"; await sqlBulkCopy.WriteToServerAsync(csvDataReader);Now IDataReader
using System.Data; namespace SaveCsvFileToSqServerWithBulkCopy; public class CsvDataReader: IDataReader { private readonly StreamReader _reader; private string[]? _currentRow; private readonly string[]? _headers; public CsvDataReader(string filePath) { _reader = new StreamReader(filePath); _headers = _reader.ReadLine()?.Split(';'); } public bool Read() { if (_reader.EndOfStream) return false; _currentRow = _reader.ReadLine()?.Split(';'); return true; } public object GetValue(int i) => _currentRow[i]; public int FieldCount => _headers.Length; public void Dispose() => _reader.Dispose(); public bool GetBoolean(int i) { throw new NotImplementedException(); } public byte GetByte(int i) { throw new NotImplementedException(); } public long GetBytes(int i, long fieldOffset, byte[]? buffer, int bufferoffset, int length) { throw new NotImplementedException(); } public char GetChar(int i) { throw new NotImplementedException(); } public long GetChars(int i, long fieldoffset, char[]? buffer, int bufferoffset, int length) { throw new NotImplementedException(); } public IDataReader GetData(int i) { throw new NotImplementedException(); } public string GetDataTypeName(int i) { throw new NotImplementedException(); } public DateTime GetDateTime(int i) { throw new NotImplementedException(); } public decimal GetDecimal(int i) { throw new NotImplementedException(); } public double GetDouble(int i) { throw new NotImplementedException(); } public Type GetFieldType(int i) { throw new NotImplementedException(); } public float GetFloat(int i) { throw new NotImplementedException(); } public Guid GetGuid(int i) { throw new NotImplementedException(); } public short GetInt16(int i) { throw new NotImplementedException(); } public int GetInt32(int i) { throw new NotImplementedException(); } public long GetInt64(int i) { throw new NotImplementedException(); } public string GetName(int i) { throw new NotImplementedException(); } public int GetOrdinal(string name) { throw new NotImplementedException(); } public string GetString(int i) { throw new NotImplementedException(); } public int GetValues(object[] values) { throw new NotImplementedException(); } public bool IsDBNull(int i) { throw new NotImplementedException(); } public object this[int i] => throw new NotImplementedException(); public object this[string name] => throw new NotImplementedException(); public void Close() { throw new NotImplementedException(); } public DataTable? GetSchemaTable() { throw new NotImplementedException(); } public bool NextResult() { throw new NotImplementedException(); } public int Depth { get; } public bool IsClosed { get; } public int RecordsAffected { get; } }Full example download from here
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 42
private void SearchForAllFilesAndPutThemInQueue(BlockingCollection<string> fileQueue, string path) { foreach (string file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)) { fileQueue.Add(file); } }Then I will read file names from queue and do something with (consumer):
private void ReadFileNamesFromQueue ( BlockingCollection<string>? fileQueue , BlockingCollection<(LatLngModel, string)>? gpsInfoQueue ) { int i = 0; if (fileQueue is null) throw new ArgumentNullException(nameof(fileQueue)); if (gpsInfoQueue is null) throw new ArgumentNullException(nameof(gpsInfoQueue)); foreach (string file in fileQueue.GetConsumingEnumerable()) { try { ExtractGpsInfoFromImageCommand extractGpsInfoFromImageCommand = new ExtractGpsInfoFromImageCommand(); extractGpsInfoFromImageCommand.ImageFileNameToReadGpsFrom = file; extractGpsInfoFromImage.Execute(extractGpsInfoFromImageCommand); if (extractGpsInfoFromImageCommand.LatLngModel is not null) { gpsInfoQueue.Add((extractGpsInfoFromImageCommand.LatLngModel, file)); } } catch (Exception ex) { Debug.WriteLine(ex.Message()); } } }Here you can download my example, little bit complicated, where I get list of file in one queue, in second I try to extract GPS info, and from third queue I am saving to CSV file file name and longitude / latitude.
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 72
A task returned by Task.Run() really is saying "I want you to execute this code separately"; the exact thread on which that code executes depends on a number of factors.So, here is first my method with async. First install Microsoft.Data.SqlClient here notice that old System.Data.SqlClient is deprecated. Now the method:
return Task.Run(() => ThreadReadFromDatabaseAsync(connectionString, sql)); private async Task ThreadReadFromDatabaseAsync(string connectionString, string sql) { DateTime start = DateTime.Now; try { await using SqlConnection connection = new SqlConnection(connectionString); await connection.OpenAsync(); await using SqlCommand command = new SqlCommand(sql, connection); command.CommandTimeout = 3600; await using SqlDataReader reader = await command.ExecuteReaderAsync(); int recdCnt = 0; while (reader.Read()) { UpdateUi.Execute($"{start} Reading using tasks record {recdCnt++}", LblRecordCount, Form); object[] values = new object[reader.FieldCount]; reader.GetValues(values); } } catch (Exception ex) { UpdateUi.Execute($"Error in task execution: {ex.Message}", LblError, Form); } finally { UpdateUi.Execute($"{DateTime.Now} Done with task execution", LblStatus, Form); } }Here notice line:
while (reader.Read())That I am not using ReadAsync. The problem is that at ReadAsync will stuck on reading from DB after few hundert records, this looks like bug described here. Now another example with thread:
var thread = new Thread(() => ThreadReadFromDatabase(connectionString, sql)) { Name = "ThreadReadFromDatabase", IsBackground = true }; thread.Start(); private void ThreadReadFromDatabase(string connectionString, string sql) { DateTime start = DateTime.Now; try { using SqlConnection connection = new SqlConnection(connectionString); connection.Open(); using SqlCommand command = new SqlCommand(sql, connection); command.CommandTimeout = 3600; using SqlDataReader reader = command.ExecuteReader(); int recdCnt = 0; while (reader.Read()) { UpdateUi.Execute($"{start} Reading using threads record {recdCnt++}", LblRecordCount, Form); object[] values = new object[reader.FieldCount]; reader.GetValues(values); } } catch (Exception ex) { UpdateUi.Execute($"Error in thread execution: {ex.Message}", LblError, Form); } finally { UpdateUi.Execute($"{DateTime.Now} Done with thread execution", LblStatus, Form); } }Full example download from here
- Details
- Written by: Stanko Milosev
- Category: C#
- Hits: 227
namespace LoggerWrapper.Logger; public class TextBoxLogger : ILogger { public TextBox? TextBox { get; set; } public void Log(LogEntry entry) { TextBox?.AppendText( $@"[{entry.Severity}] {DateTime.Now} {entry.Message} {entry.Exception}"); TextBox?.AppendText(Environment.NewLine); } }Notice:
public TextBox? TextBox { get; set; }Later, I will connect this property to the actual TextBox in Form1. Here’s what my Program.cs looks like:
using LoggerWrapper.Logger; namespace LoggerWrapper { internal static class Program { [STAThread] static void Main() { ApplicationConfiguration.Initialize(); var textBoxLogger = new TextBoxLogger(); var someDiClassHandler = new SomeDiClassHandler(textBoxLogger); Form1 form1 = new Form1(someDiClassHandler); textBoxLogger.TextBox = form1.TbLogger; Application.Run(form1); } } }Notice:
textBoxLogger.TextBox = form1.TbLogger;In Form1, I introduced a property named TbLogger:
namespace LoggerWrapper; public partial class Form1 : Form { public TextBox? TbLogger { get; } private readonly SomeDiClassHandler _someDiClassHandler; public Form1(SomeDiClassHandler someDiClassHandler) { InitializeComponent(); TbLogger = tbLogger; _someDiClassHandler = someDiClassHandler; } private void btnStart_Click(object sender, EventArgs e) { SomeDiClassCommand someDiClassCommand = new SomeDiClassCommand(); _someDiClassHandler.Execute(someDiClassCommand); } }After creating Form1 I will assign TextBox to my TextBoxLogger, and in Form1 constructor I will assign TbLogger to real TextBox, in my case tbLogger:
TbLogger = tbLogger;Example download from here