它执行@RefreshDataGrid()就好了但是当我尝试执行findCommand()时它给了我这个例外:
抛出异常:System.Windows.Forms.dll中的“System.InvalidOperationException” 跨线程操作无效:控制'dgvMySqlKBer'从其创建的线程以外的线程访问。
如果您需要更多信息,请随时询问,无论如何这里是代码。
我发现它与this.Load += Form1_Load;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using Discord;
using System.Media;
using System.Text.RegularExpressions;
using System.Data;
using System.ComponentModel;
using MySql.Data.MySqlClient;
using System.Linq;
namespace DiscordSongRequest
{
public partial class Form1 : Form
{
string ipaddress = "localhost";
string username = "root";
string password = "";
private DiscordClient client;
SoundPlayer player = new SoundPlayer();
Random random = new Random();
public static readonly Regex YoutubeVideoRegex = new Regex(@"youtu(?:\.be|be\.com)/(?:.*v(?:/|=)|(?:.*/)?)([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase);
public Form1()
{
this.Load += Form1_Load;
}
private void Form1_Load(object sender, System.EventArgs e)
{
Task.Factory.StartNew(() => ConnectClient());
InitializeComponent();
dgvMySqlKBer.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
RefreshDataGrid();
}
private void RefreshDataGrid()
{
try
{
string MyConnection = "datasource=" + ipaddress + ";username=" + username + ";password=" + password + "";
string Query = "select * from discordsongrequest.commands;";
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MySqlCommand MyCommand = new MySqlCommand(Query, MyConn);
MyConn.Open();
MySqlDataAdapter MyAdapter = new MySqlDataAdapter();
MyAdapter.SelectCommand = MyCommand;
DataTable dTable = new DataTable();
MyAdapter.Fill(dTable);
dgvMySqlKBer.DataSource = dTable;
MyConn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private async Task ConnectClient()
{
try
{
client = new DiscordClient();
client.MessageCreated += async (s, e) =>
{
switch (e.Message.Text)
{
case "!stop":
webBrowser1.Navigate("about:blank");
break;
case "!hallo":
findCommand(e.Message.Text);
player.Play();
break;
case "!play":
break;
case "!random":
int randomNumber = random.Next(0, 1000);
await client.SendMessage(e.Message.Channel, "Random! You roll a: " + Convert.ToString(randomNumber) + ".");
break;
case "!coin":
randomNumber = random.Next(0, 2);
if (randomNumber == 0)
{
await client.SendMessage(e.Message.Channel, "Coinflip! it lands on: Heads.");
}
else
{
await client.SendMessage(e.Message.Channel, "Coinflip! it lands on: Tails.");
}
break;
default:
if (e.Message.Text.StartsWith("!play"))
{
string l = e.Message.Text;
l = (l.StartsWith("!play")) ? l.Substring(6) : l;
checkForLink(l);
}
break;
}
};
await client.Connect("username", "password");
await client.AcceptInvite("invitecode");
}
catch
{
}
}
private void checkForLink(string l)
{
try
{
Match youtubeMatch = YoutubeVideoRegex.Match(l);
if (youtubeMatch.Success)
{
Uri uri = new Uri(l);
webBrowser1.Url = uri;
}
}
catch
{
}
}
private void findCommand(string command)
{
string MyConnection = "datasource=" + ipaddress + ";username=" + username + ";password=" + password + "";
string Query = "select * from discordsongrequest.commands where command = '" + command + "';";
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MySqlCommand MyCommand = new MySqlCommand(Query, MyConn);
MyConn.Open();
MySqlDataAdapter MyAdapter = new MySqlDataAdapter();
MyAdapter.SelectCommand = MyCommand;
DataTable dTable = new DataTable();
MyAdapter.Fill(dTable);
dgvMySqlKBer.DataSource = dTable;
MyConn.Close();
}
}
}
答案 0 :(得分:-2)
看看这里:How to: Manipulate Controls from Threads
dgvMySqlKBer对象是在主事件线程中创建的,并且您尝试从另一个不是有效操作的线程中访问它。您需要在该对象中调用invoke并将其传递给Action。
private void findCommand(string command)
{
string MyConnection = "datasource=" + ipaddress + ";username=" + username + ";password=" + password + "";
string Query = "select * from discordsongrequest.commands where command = '" + command + "';";
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MySqlCommand MyCommand = new MySqlCommand(Query, MyConn);
MyConn.Open();
MySqlDataAdapter MyAdapter = new MySqlDataAdapter();
MyAdapter.SelectCommand = MyCommand;
DataTable dTable = new DataTable();
MyAdapter.Fill(dTable);
dgvMySqlKBer.Invoke((MethodInvoker)delegate
{
dgvMySqlKBer.DataSource = dTable;
});
dgvMySqlKBer.DataSource = dTable;
MyConn.Close();
}