我一直在試圖修改一些GUI元素之前/之後,我試圖同步和異步執行的TCP連接。嘗試修改另一個任務的GUI
public async void ConnectAsync(String h, String p, String n)
{
if (connected)
return;
try
{
hostname = new HostName(h);
port = p;
nickname = n;
await sock.ConnectAsync(hostname, port);
connected = true;
if (Connected != null)
Connected(this, EventArgs.Empty);
}
catch (Exception e)
{
sock.Dispose();
hostname = null;
port = null;
nickname = null;
if (ConnectionFailed != null)
ConnectionFailed(this, EventArgs.Empty);
}
}
此方法以上由GUI類(下面的代碼)調用:
private void ConnectButtonClicked(object sender, RoutedEventArgs e)
{
string nickname;
if (Bar.Visibility == Windows.UI.Xaml.Visibility.Visible)
Bar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
if (Status.Visibility == Windows.UI.Xaml.Visibility.Collapsed)
Status.Visibility = Windows.UI.Xaml.Visibility.Visible;
qc.ConnectionFailed += new ConnectionFailedEventHandler(ConnectionFailedEventHandler);
qc.Connected += new ConnectedEventHandler(ConnectedEventHandler);
nickname = Nickname.Text;
/* HERE */
Task.Run(() => qc.ConnectAsync("irc.quakenet.org", "6667", nickname));
updateStatus("Connecting...");
ConnectButton.IsEnabled = false;
Nickname.IsEnabled = false;
ProgLanguages.IsEnabled = false;
}
見,該方法提出了兩個不同的事件..
如果我調用此方法這樣的代碼與Task.Run(..)一起,引發這些事件,並在處理它們時,代碼嘗試通過此線程修改GUI並拋出異常。
如果我沒有Task.Run(..)調用方法,GUI凍結,我不能修改元素來顯示它是「連接」等等。
任何想法我怎麼能做到這一點?
你有沒有試過在你的Task.Run前面等待,這樣它可以讓後臺任務完成(而不是阻止UI)。 YOu需要爲該底部方法簽名添加異步,並使其返回任務 – James 2013-05-06 22:48:16
您遇到的異常是什麼?它是'跨線程操作無效'嗎? – PoweredByOrange 2013-05-06 22:51:34
同意@James。你更好的設計將是等待ConnectAsync。並返回指示連接狀態的結果。無需事件。 – jure 2013-05-06 22:54:28