相关疑难解决方法(0)

检测是否在WPF和Winforms中的UI线程上

我在下面编写了一个断言方法Ensure.CurrentlyOnUiThread(),用于检查当前线程是否为UI线程.

  • 这在检测Winforms UI线程时是否可靠?
  • 我们的应用程序是混合WPF和Winforms,如何最好地检测有效的WPF UI线程?
  • 有一个更好的方法吗?也许代码合同?

Ensure.cs

using System.Diagnostics;
using System.Windows.Forms;

public static class Ensure
{
    [Conditional("DEBUG")]
    public static void CurrentlyOnUiThread()
    {
        if (!Application.MessageLoop)
        {
            throw new ThreadStateException("Assertion failed: not on the UI thread");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c# wpf assertions winforms

42
推荐指数
5
解决办法
4万
查看次数

在主UI线程的Continuation中,SynchronizationContext.Current为null

我一直在试图追查了以下问题的WinForms应用程序:
SynchronizationContext.Current是一个任务的延续(即空.ContinueWith这是主要的线程上运行)(我预计当前同步上下文是System.Windows.Forms.WindowsFormsSynchronizationContext).

以下是演示此问题的Winforms代码:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TaskScheduler ts = TaskScheduler.FromCurrentSynchronizationContext(); // Get the UI task scheduler

            // This line is required to see the issue (Removing this causes the problem to go away), since it changes the codeflow in 
            // \SymbolCache\src\source\.NET\4\DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\Threading\ExecutionContext.cs\1305376\ExecutionContext.cs
            // at line 435
            System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");

            var task = Task.Factory.StartNew(() => { });
            var cont …
Run Code Online (Sandbox Code Playgroud)

c# winforms synchronizationcontext task-parallel-library

21
推荐指数
1
解决办法
5809
查看次数

钩子事件Outlook VSTO在主线程上继续工作

我开发了一个Outlook VSTO插件.某些任务应该在后台线程上完成.通常,检查本地数据库中的某些内容或调用Web请求.阅读了几篇文章之后,我放弃了在后台线程中调用Outlook对象模型(OOM)的想法.

我有一些wpf控件,我成功地设法使用.NET 40 TPL执行异步任务,并在完成时"完成"主VSTA线程中的作业(即访问UI或OOM).

为此,我使用了以下形式的语法:

Task<SomeResult> task = Task.Factory.StartNew(()=>{
    //Do long tasks that have nothing to do with UI or OOM
    return SomeResult();
});

//now I need to access the OOM
task.ContinueWith((Task<SomeResult> tsk) =>{
   //Do something clever using SomeResult that uses the OOM
},TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但现在我想在OOM中挂钩没有Form/WPF控件的事件时做类似的事情.确切地说,我的问题来自于TaskScheduler.FromCurrentSynchronizationContext()抛出异常的事实.

例如,

Items inboxItems = ...;
inboxItems.ItemAdd += AddNewInboxItems;

private void AddNewInboxItems(object item)
{
    Task<SomeResult> task = Task.Factory.StartNew(()=>{
    //Do long tasks that have nothing to do with OOM
    return SomeResult()});


   var scheduler = …
Run Code Online (Sandbox Code Playgroud)

c# outlook multithreading vsto outlook-addin

19
推荐指数
1
解决办法
1200
查看次数

使用Visual Studio 2012开发.NET 4.0(Windows XP)

.NET 4.5是就地升级,因此取代了.NET 4.0.因此,当我使用Visual Studio 2012安装.NET 4.5时,我无法再为.NET 4.0开发应用程序.

由于Windows XP不支持.NET 4.5,如何在安装Visual Studio 2012后维护现有的.NET 4.0应用程序仍然必须在Windows XP下运行

到目前为止,只要安装了VS2003,我就可以为每个版本甚至.NET 1.1开发.NET应用程序.我没有问题微软不支持XP上的.NET 4.5,我认为切断旧东西是可以的.但是,由于我们仍然有客户使用Windows XP,我们需要能够在.NET 4.5的同时创建.NET 4.0程序.

编辑:

我刚刚遇到了第一个不兼容问题:我在Windows Server 2012上安装了VS 2012.我创建了一个面向.NET 4.0的项目.在blend 4.0中,我创建了一个复选框的控件模板的副本.生成的模板包含仅在.NET 4.5下可用的颜色的引用.解决方案无法再编译.但是,同样的情况在我的Windows 7安装上运行正常.

我假设.NET 4.5的安装已经取代了我的标准控件的控件模板.因此我不能再创建副本了.

windows-xp .net-4.0 expression-blend .net-4.5

5
推荐指数
1
解决办法
1万
查看次数

在多个任务中共享TaskScheduler实例

我创建了一个TaskScheduler,我它作为两个不同任务的参数传递.

这样做有什么问题吗?我应该为每个任务创建一个新的TaskScheduler实例吗?

这是示例示例(为简单起见,每个任务中的实际代码都被删除)

var uiSch = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();

var t1 = Task.Factory.StartNew<List<Carrier>>(() =>
                    {
                        //does stuff
                    })
                    .ContinueWith(previous =>
                        {
                            //does stuff
                        },
                        System.Threading.CancellationToken.None,
                        TaskContinuationOptions.OnlyOnRanToCompletion,
                        uiSch);

var t2 = Task.Factory.StartNew<List<Logic.WarehouseLogic.Warehouse>>(() =>
                    {
                        //does stuff
                    })
                    .ContinueWith(previous =>
                        {
                            //does stuff
                        },
                        System.Threading.CancellationToken.None,
                        TaskContinuationOptions.OnlyOnRanToCompletion,
                        uiSch);
Run Code Online (Sandbox Code Playgroud)

[EDIT1]

我的问题部分与以下错误有关:'当前的SynchronizationContext可能不会被用作TaskScheduler'可在此处找到修复

c# task-parallel-library

0
推荐指数
1
解决办法
156
查看次数