我试图在任务上设置公寓状态但是看不到这样做的选项.有没有办法使用任务执行此操作?
for (int i = 0; i < zom.Count; i++)
{
Task t = Task.Factory.StartNew(zom[i].Process);
t.Wait();
}
Run Code Online (Sandbox Code Playgroud) 我试图在一个小的.net 4.0应用程序(使用Visual Studio 2010编写,如果这很重要)中使用任务,需要在Windows 2003上工作并使用带调色板参数的WriteableBitmap.
因此,使用所述类的代码必须作为STA线程运行,以避免它抛出无效的强制转换异常(如果您感兴趣,请参阅此处了解我需要STA线程的原因,但这不是我的问题的主旨).
因此,我检查了堆栈溢出并遇到了如何创建运行STA线程的任务(TPL)?和目前的SynchronizationContext可能不被用作的TaskScheduler -完美的,所以现在我知道该怎么做,只是...
这是一个小控制台应用程序:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace TaskPlayingConsoleApplication
{
class Program
{
[STAThread]
static void Main()
{
Console.WriteLine("Before Anything: "
+ Thread.CurrentThread.GetApartmentState());
SynchronizationContext.SetSynchronizationContext(
new SynchronizationContext());
var cts = new CancellationTokenSource();
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task.Factory.StartNew(
() => Console.WriteLine(
"In task: " + Thread.CurrentThread.GetApartmentState()),
cts.Token,
TaskCreationOptions.None,
scheduler);
task.ContinueWith(t =>
Console.WriteLine(
"In continue: " + Thread.CurrentThread.GetApartmentState()),
scheduler); …Run Code Online (Sandbox Code Playgroud) 可能重复:
如何创建运行STA线程的任务(TPL)?
我正在使用以下代码:
var task = Task.Factory.StartNew<List<NewTwitterStatus>>(
() => GetTweets(securityKeys),
TaskCreationOptions.LongRunning);
Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
var result = task.Result; // ERROR!!! The calling thread cannot access this object because a different thread owns it.
RecentTweetList.ItemsSource = result;
Visibility = result.Any() ? Visibility.Visible : Visibility.Hidden;
}));
Run Code Online (Sandbox Code Playgroud)
我收到了错误:
var result = task.Result; // ERROR!!! The calling thread cannot access this object because a different thread owns it.
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能解决这个问题?
我知道在这个主题上有一些关于SO的答案,但是我无法让任何解决方案适合我.我试图从一个从datatemplate中发出的ICommand打开一个新窗口.当实例化新窗口时(在"new MessageWindowP"中),以下两者都会出现上述错误:
使用TPL/FromCurrentSynchronizationContext 更新:有效
public class ChatUserCommand : ICommand
{
public void Execute(object sender)
{
if (sender is UserC)
{
var user = (UserC)sender;
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(new Action<object>(CreateMessageWindow), user,CancellationToken.None, TaskCreationOptions.None,scheduler);
}
}
private void CreateMessageWindow(object o)
{
var user = (UserC)o;
var messageP = new MessageWindowP();
messageP.ViewModel.Participants.Add(user);
messageP.View.Show();
}
}
Run Code Online (Sandbox Code Playgroud)
使用ThreadStart: 更新:不推荐,请参阅Jon的回答
public class ChatUserCommand : ICommand
{
public void Execute(object sender)
{
if (sender is UserC)
{
var user = (UserC)sender;
var t = new …Run Code Online (Sandbox Code Playgroud) 我正在VS2010中开发VSTO Outlook加载项。在该ThisAddIn_Startup方法(外接程序启动时称为)中,我的代码需要检查Outlook是否在公司网络上运行。如果Outlook未在网络上运行,则大约需要3秒钟才能得到答案。因此,我将代码包装在一个Task中,以使其运行Async以确保它在检查时不会挂起Outlook。
例如
bool onNetwork = false;
Task task = Task.Factory.StartNew(() =>
{
onNetwork = IsConnectedToNetwork();
});
Run Code Online (Sandbox Code Playgroud)
完成检查后,需要加载并显示相关表格。所以我将代码更改为:
Task task = Task.Factory.StartNew(() =>
{
if (IsConnectedToNetwork())
{
OnNetworkForm onNetworkForm = new OnNetworkForm();
onNetworkForm.Show();
}
else
{
OffNetworkForm offNetworkForm = new OffNetworkForm();
offNetworkForm.Show();
}
});
Run Code Online (Sandbox Code Playgroud)
但是需要将窗体加载到UI线程上。否则,InvalidOptionationException当它尝试加载并显示带有消息的表单时,我得到一个提示:
调用线程必须是STA,因为许多UI组件都需要STA。
我的问题是如何使窗体加载到UI线程上?
请注意
我不能使用await,因为那是C#5.0,而VS 2010不支持C#5.0。而且ThisAddin类不是控件,因此没有可用的BeginInvokeor Invoke方法。