Sql server code>,SqlCommand,和SqlDataReader,所以SQL引用了我的SQL控制类。我将在上面更新…为什么要探测网格上每个X和Y坐标的结果集?为什么不迭代结果集并使用它包含的X,Y,Fill值呢?首先,循环有什么问题?它会永远消失吗?我不是1
Sql server code>,SqlCommand,和SqlDataReader,所以SQL引用了我的SQL控制类。我将在上面更新…为什么要探测网格上每个X和Y坐标的结果集?为什么不迭代结果集并使用它包含的X,Y,Fill值呢?首先,循环有什么问题?它会永远消失吗?我不是1,sql-server,vb.net,visual-studio,Sql Server,Vb.net,Visual Studio,code>,SqlCommand,和SqlDataReader,所以SQL引用了我的SQL控制类。我将在上面更新…为什么要探测网格上每个X和Y坐标的结果集?为什么不迭代结果集并使用它包含的X,Y,Fill值呢?首先,循环有什么问题?它会永远消失吗?我不是100%,但是如果FILL有一个值,那么Do While行
code>,
SqlCommand
,和SqlDataReader
,所以SQL引用了我的SQL控制类。我将在上面更新…为什么要探测网格上每个X和Y坐标的结果集?为什么不迭代结果集并使用它包含的X,Y,Fill值呢?首先,循环有什么问题?它会永远消失吗?我不是100%,但是如果FILL
有一个值,那么Do While行
循环将永远运行?感谢您花时间键入@Dai,我将处理它并返回给您!为什么.ConfigureAwait(false)
在这里?它看起来像一个WinForms项目。@Jimi正确。我添加它是因为它是WinForms:这是因为LoadMapperTableAsync
中有一个紧密的循环(特别是while(wait rdr.ReadAsync)
循环)您确实不希望继续在UI线程上继续:您希望它在第一个可用的线程池线程上继续,因此configurewait(false)
。方法中未使用UI控件或对象,因此ConfigureAwait(false)
将产生最佳性能。可靠。OP如何调用LoadAsync()ConfigureAwait(false)
在这里可能很有用,因为ConvertTo2DArray(列表)代码>:如果这是在线程池线程中运行的,您就不需要它了(我实际上并没有提出不同的方法,这是OP需要考虑/测试的东西)。绘制网格可能需要20-30ms,当数据准备就绪时。
Public Sub LoadMap()
Dim Fill As Integer = 0
Dim Row As Integer = 0
Dim X As Integer = 0
Dim Y As Integer = 0
SQL.ExecQuery("SELECT * FROM Mapper_Table")
Do While Y <= MapHeight
'Ultimate exit statement: stop loading cells when Y becomes greater than the MapHeight...
Do While X <= MapWidth
'Row Exit Statement: When X reaches 100, its time to start on the next row...
Do While Row < SQL.RecordCount '12
'I only want to search as many rows as there are saved locations, otherwise the cell must be empty and therefore blank...
If X = SQL.DBDT.Rows(Row).Item("X") And Y = SQL.DBDT.Rows(Row).Item("Y") Then
'If the current (X,Y) is a match to the database row, then we take the stored colour...
Fill = SQL.DBDT.Rows(Row).Item("Fill")
End If
'If Fill is taken, we can colour the square; otherwise, we should look in the next row...
If Fill <> 0 Then
Map(X, Y, 0) = Fill
End If
** Row = Row + 1 **
Loop
'Once we have looked in all the rows for out cell, it is either coloured in or not; we can move onto the next cell in the row; a.k.a...
X = X + 1
** Fill = 0 **
Loop
'Once we have looked for all the cells in our row, we can move onto the next one; a.k.a...
X = 0
Y = Y + 1
Loop
'Once we get to the end of the map, it should be loaded!
End Sub
public enum FillColor {
None = 0, // It's important that zero represents "empty" or "not set" due to .NET's rules on default values for value-types like enums.
Red = 1,
Blue = 2,
// etc
}
public static async Task< List<( Int32 x, Int32 y, FillColor fill )> > LoadMapperTableAsync()
{
const String connectionString = "...";
using( SqlConnection c = new SqlConnection( connectionString ) )
using( SqlCommand cmd = c.CreateCommand() )
{
await c.OpenAsync().ConfigureAwait(false);
cmd.CommandText = "SELECT x, y, fill FROM Mapper_Table"; // NEVER EVER USE `SELECT * FROM` in application code!!!!!! Always explicitly name your columns!
using( SqlDataReader rdr = await cmd.ExecuteReaderAsync().ConfigureAwait(false) )
{
List<( Int32 x, Int32 y, FillColor fill )> list = new List<( Int32 x, Int32 y, FillColor fill )>();
while( await rdr.ReadAsync().ConfigureAwait(false) )
{
Int32 x = rdr.GetInt32( 0 ); // Add `rdr.IsDBNull()` guards, if necessary!
Int32 y = rdr.GetInt32( 1 );
Int32 fill = rdr.GetInt32( 2 );
list.Add( ( x, y, (FillColor)fill ) );
}
return list;
}
}
}
public static FillColor[,] ConvertTo2DArray( IEnumerable< ( Int32 x, Int32 y, FillColor fill ) > values )
{
const Int32 MAP_WIDTH = 100;
const Int32 MAP_HEIGHT = 100;
FillColor[,] map = new FillColor[ MAP_HEIGHT, MAP_WIDTH ];
// Do note that 2D arrays in .NET are slooooow: https://stackoverflow.com/questions/468832/why-are-multi-dimensional-arrays-in-net-slower-than-normal-arrays
foreach( ( Int32 x, Int32 y, FillColor fill ) in values )
{
// Skip-over invalid data:
if( x < 0 || x > MAP_WIDTH ) continue;
if( y < 0 || y > MAP_HEIGHT ) continue;
map[ y, x ] = fill;
}
return map;
}
public static async Task<FillColor[,]> LoadAsync()
{
List<( Int32 x, Int32 y, FillColor fill )> list = await LoadMapperTableAsync().ConfigureAwait(false);
return ConvertTo2DArray( list );
}
Public Sub LoadMap()
Dim Fill As Integer = 0
Dim Row As Integer = 0
Dim X As Integer = 0
Dim Y As Integer = 0
'Experiment: Sets X and Y to CurrentLocation with Record that has Fill. Works
'Experiment: If Row(0) is not correct, try other rows.
'Experiment: Loop the loop for all X and Y's
SQL.ExecQuery("SELECT X,Y,Fill FROM Mapper_Table")
Do While Y <= MapHeight
'Ultimate exit statement: stop loading cells when Y becomes greater than the MapHeight...
Do While X <= MapWidth
'Row Exit Statement: When X reaches 100, its time to start on the next row...
Do While Row < SQL.RecordCount
'I only want to search as many rows as there are saved locations, otherwise the cell must be empty and therefore blank...
If X = SQL.DBDT.Rows(Row).Item("X") And Y = SQL.DBDT.Rows(Row).Item("Y") Then
'If the current (X,Y) is a match to the database row, then we take the stored colour...
Fill = SQL.DBDT.Rows(Row).Item("Fill")
'And paint the cell...
Map(X, Y, 0) = Fill
Row = SQL.RecordCount
'Otherwise, we look at the next row
Else Row = Row + 1
End If
Loop
'Once we have looked in all the rows for out cell, it is either coloured in or not; we can move onto the next cell in the row; a.k.a...
X = X + 1
Row = 0
Fill = 0
Loop
'Once we have looked for all the cells in our row, we can move onto the next one; a.k.a...
X = 0
Y = Y + 1
Loop
'Once we get to the end of the map, it should be loaded!
End Sub