UWP IOT-Core 应用程序 System.Exception:应用程序调用了为不同线程编组的接口
UWP IOT-Core App System.Exception: The application called an interface that was marshalled for a different thread
我无法使用 运行 在 Windows 10 IoT Core 上的应用程序。所有 Classes 都工作正常,除了通过 JSON 创建 CSV 文件并应该将其作为电子邮件发送的那个。
当代码到达 "ReturnToMainPage()" 函数时,抛出异常 "System.Exception: The application called an interface that was marshalled for a different thread"。
"funny" 事情是,邮件正在发送,我收到了邮件,但程序不会在发送电子邮件后切换回主页。
这是 Class 的代码:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using EASendMail;
namespace PratschZahlstation
{
public sealed partial class MailChoice : Page
{
private TextBlock _headerText;
private ComboBox _mailComboBox;
private Button _execute;
private Button _abort;
private EnDecode _coder = EnDecode.get_EnDecodeSingleton();
private string _mailto = null;
public MailChoice()
{
this.InitializeComponent();
Init();
}
private void Init()
{
_headerText = HeaderText;
_mailComboBox = MailAdresses;
_mailComboBox.Items.Add("---");
_mailComboBox.Items.Add("dummy@mail.com");
_mailComboBox.SelectedIndex = 0;
_execute = DoFunction;
_abort = DoExit;
}
private void DoFunction_Click(object sender, RoutedEventArgs e)
{
string selectedMail = this._mailComboBox.SelectedItem.ToString();
if(selectedMail == "---")
{
_headerText.Text = "Bitte eine Emailadresse aus der Liste auswählen.";
}
else
{
_headerText.Text = "CSV wird erstellt und per Mail versendet!";
_execute.IsEnabled = false;
_abort.IsEnabled = false;
_mailComboBox.IsEnabled = false;
_mailto = selectedMail;
DateTime date = DateTime.Now;
string strippedDate = date.ToString("yyyy-MM-dd") + " 00:00:01";
GetDataForCSV(strippedDate);
}
}
private async void GetDataForCSV(string dateAsString)
{
string correctedDate = "2019-07-01 00:00:01";//dateAsString;
string date = _coder.Base64Encode(correctedDate);
HttpClient _client = new HttpClient();
Uri _uri = new Uri("URI TO JSON-API");
_client.BaseAddress = _uri;
var request = new HttpRequestMessage(HttpMethod.Post, _uri);
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("mode", "10"));
keyValues.Add(new KeyValuePair<string, string>("date", date));
request.Content = new FormUrlEncodedContent(keyValues);
var response = await _client.SendAsync(request);
string sContent = await response.Content.ReadAsStringAsync();
keyValues = null;
if (sContent != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(sContent);
string json = Encoding.UTF8.GetString(bytes);
if (!json.Contains("success"))
{
List<CSV_SQL_Json_Object> _Json = JsonConvert.DeserializeObject<List<CSV_SQL_Json_Object>>(json);
response.Dispose();
request.Dispose();
_client.Dispose();
if (_Json.Count == 0)
{
}
else
{
CreateCSV(_Json);
}
}
else
{
List<JSON_Status> _Json = JsonConvert.DeserializeObject<List<JSON_Status>>(json);
_headerText.Text = "Es ist der Folgender Fehler aufgetreten - Errorcode: \"" + _coder.Base64Decode(_Json[0].success) + "\"\r\nFehlermeldung: \"" + _coder.Base64Decode(_Json[0].message) + "\"";
_Json.Clear();
response.Dispose();
request.Dispose();
_client.Dispose();
}
}
}
private async void CreateCSV(List<CSV_SQL_Json_Object> contentForCSV)
{
DateTime date = DateTime.Now;
string csvName = date.ToString("yyyy-MM-dd") + ".csv";
StorageFolder storageFolder = KnownFolders.MusicLibrary;
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
await FileIO.WriteTextAsync(csvFile, "Column1;Column2;Column3;Column4;\n");
foreach (var item in contentForCSV)
{
await FileIO.AppendTextAsync(csvFile, _coder.Base64Decode(item.Object1) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object2)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object3)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object4)) + "\n");
}
SendEmail(_mailto, csvName);
}
private async void SendEmail(string mailto, string csvName)
{
try
{
SmtpMail oMail = new SmtpMail("Mail");
SmtpClient oSmtp = new SmtpClient();
oMail.From = new MailAddress("noreply@dummy.com");
oMail.To.Add(new MailAddress(mailto));
oMail.Subject = "The Subject";
oMail.HtmlBody = "<font size=5>MailText</font>";
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
string attfile = file.Path;
Attachment oAttachment = await oMail.AddAttachmentAsync(attfile);
SmtpServer oServer = new SmtpServer("mail.dummy.com");
oServer.User = "dummyuser";
oServer.Password = "dummypass";
oServer.Port = 587;
oServer.ConnectType = SmtpConnectType.ConnectSSLAuto;
await oSmtp.SendMailAsync(oServer, oMail);
}
catch (Exception ex)
{
string error = ex.ToString();
_abort.IsEnabled = true;
}
ReturnToMainPage(); //This is where the Error Happens
}
private void ReturnToMainPage()
{
this.Frame.Navigate(typeof(MainPage));
}
private void DoExit_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
}
这可能是线程问题。只能在主线程上导航。
您可能想尝试 编组呼叫 在:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
}
);
来源:
The application called an interface that was marshalled for a different thread - Windows Store App
就像Tobonaut说的,你可以用Dispatcher.RunAsync
调用Navigation
,成功了。
但你的问题可能不是这个
我复制了你的代码,复现了你的问题,发现你调用读写文件有问题:
// Your code
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
如果您删除 .AsTask().ConfigureAwait(false)
,导航将可用。
此致。
我无法使用 运行 在 Windows 10 IoT Core 上的应用程序。所有 Classes 都工作正常,除了通过 JSON 创建 CSV 文件并应该将其作为电子邮件发送的那个。
当代码到达 "ReturnToMainPage()" 函数时,抛出异常 "System.Exception: The application called an interface that was marshalled for a different thread"。
"funny" 事情是,邮件正在发送,我收到了邮件,但程序不会在发送电子邮件后切换回主页。
这是 Class 的代码:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using EASendMail;
namespace PratschZahlstation
{
public sealed partial class MailChoice : Page
{
private TextBlock _headerText;
private ComboBox _mailComboBox;
private Button _execute;
private Button _abort;
private EnDecode _coder = EnDecode.get_EnDecodeSingleton();
private string _mailto = null;
public MailChoice()
{
this.InitializeComponent();
Init();
}
private void Init()
{
_headerText = HeaderText;
_mailComboBox = MailAdresses;
_mailComboBox.Items.Add("---");
_mailComboBox.Items.Add("dummy@mail.com");
_mailComboBox.SelectedIndex = 0;
_execute = DoFunction;
_abort = DoExit;
}
private void DoFunction_Click(object sender, RoutedEventArgs e)
{
string selectedMail = this._mailComboBox.SelectedItem.ToString();
if(selectedMail == "---")
{
_headerText.Text = "Bitte eine Emailadresse aus der Liste auswählen.";
}
else
{
_headerText.Text = "CSV wird erstellt und per Mail versendet!";
_execute.IsEnabled = false;
_abort.IsEnabled = false;
_mailComboBox.IsEnabled = false;
_mailto = selectedMail;
DateTime date = DateTime.Now;
string strippedDate = date.ToString("yyyy-MM-dd") + " 00:00:01";
GetDataForCSV(strippedDate);
}
}
private async void GetDataForCSV(string dateAsString)
{
string correctedDate = "2019-07-01 00:00:01";//dateAsString;
string date = _coder.Base64Encode(correctedDate);
HttpClient _client = new HttpClient();
Uri _uri = new Uri("URI TO JSON-API");
_client.BaseAddress = _uri;
var request = new HttpRequestMessage(HttpMethod.Post, _uri);
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("mode", "10"));
keyValues.Add(new KeyValuePair<string, string>("date", date));
request.Content = new FormUrlEncodedContent(keyValues);
var response = await _client.SendAsync(request);
string sContent = await response.Content.ReadAsStringAsync();
keyValues = null;
if (sContent != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(sContent);
string json = Encoding.UTF8.GetString(bytes);
if (!json.Contains("success"))
{
List<CSV_SQL_Json_Object> _Json = JsonConvert.DeserializeObject<List<CSV_SQL_Json_Object>>(json);
response.Dispose();
request.Dispose();
_client.Dispose();
if (_Json.Count == 0)
{
}
else
{
CreateCSV(_Json);
}
}
else
{
List<JSON_Status> _Json = JsonConvert.DeserializeObject<List<JSON_Status>>(json);
_headerText.Text = "Es ist der Folgender Fehler aufgetreten - Errorcode: \"" + _coder.Base64Decode(_Json[0].success) + "\"\r\nFehlermeldung: \"" + _coder.Base64Decode(_Json[0].message) + "\"";
_Json.Clear();
response.Dispose();
request.Dispose();
_client.Dispose();
}
}
}
private async void CreateCSV(List<CSV_SQL_Json_Object> contentForCSV)
{
DateTime date = DateTime.Now;
string csvName = date.ToString("yyyy-MM-dd") + ".csv";
StorageFolder storageFolder = KnownFolders.MusicLibrary;
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
await FileIO.WriteTextAsync(csvFile, "Column1;Column2;Column3;Column4;\n");
foreach (var item in contentForCSV)
{
await FileIO.AppendTextAsync(csvFile, _coder.Base64Decode(item.Object1) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object2)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object3)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object4)) + "\n");
}
SendEmail(_mailto, csvName);
}
private async void SendEmail(string mailto, string csvName)
{
try
{
SmtpMail oMail = new SmtpMail("Mail");
SmtpClient oSmtp = new SmtpClient();
oMail.From = new MailAddress("noreply@dummy.com");
oMail.To.Add(new MailAddress(mailto));
oMail.Subject = "The Subject";
oMail.HtmlBody = "<font size=5>MailText</font>";
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
string attfile = file.Path;
Attachment oAttachment = await oMail.AddAttachmentAsync(attfile);
SmtpServer oServer = new SmtpServer("mail.dummy.com");
oServer.User = "dummyuser";
oServer.Password = "dummypass";
oServer.Port = 587;
oServer.ConnectType = SmtpConnectType.ConnectSSLAuto;
await oSmtp.SendMailAsync(oServer, oMail);
}
catch (Exception ex)
{
string error = ex.ToString();
_abort.IsEnabled = true;
}
ReturnToMainPage(); //This is where the Error Happens
}
private void ReturnToMainPage()
{
this.Frame.Navigate(typeof(MainPage));
}
private void DoExit_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
}
这可能是线程问题。只能在主线程上导航。
您可能想尝试 编组呼叫 在:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
}
);
来源:
The application called an interface that was marshalled for a different thread - Windows Store App
就像Tobonaut说的,你可以用Dispatcher.RunAsync
调用Navigation
,成功了。
但你的问题可能不是这个
我复制了你的代码,复现了你的问题,发现你调用读写文件有问题:
// Your code
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
如果您删除 .AsTask().ConfigureAwait(false)
,导航将可用。
此致。