2015-09-04 57 views
0

它执行@RefreshDataGrid()就好了,但是当我尝试执行findCommand()它给了我这样的例外:跨线程操作无效AMD试图找到一个解决方案

抛出异常:“系统。 InvalidOperationException'在System.Windows.Forms.dll中 跨线程操作无效:控制'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(); 
     } 

    } 
} 

回答

-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(); 
    } 
+0

请**停止**标记此帖以供版主注意,并要求版主从帖子中删除downvote。版主不能改变投票。 – Matt

+0

呃,比这个过程有什么不对吗? – Marco

+0

是什么让你觉得呢?堆栈溢出允许用户按自己的意愿进行投票(提供的投票不是欺诈或针对性的;在这里也不适用)。投票应该代表社区的共识;不是一个主持人的感觉。如果我们允许主持人按照他们的意愿使投票无效,我们就会失去这个观点。 – Matt